Octopus
electrons.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2009 X. Andrade
3!! Copyright (C) 2020 M. Oliveira
4!!
5!! This program is free software; you can redistribute it and/or modify
6!! it under the terms of the GNU General Public License as published by
7!! the Free Software Foundation; either version 2, or (at your option)
8!! any later version.
9!!
10!! This program is distributed in the hope that it will be useful,
11!! but WITHOUT ANY WARRANTY; without even the implied warranty of
12!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13!! GNU General Public License for more details.
14!!
15!! You should have received a copy of the GNU General Public License
16!! along with this program; if not, write to the Free Software
17!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18!! 02110-1301, USA.
19!!
20
21#include "global.h"
22
23
24module electrons_oct_m
25 use accel_oct_m
33 use debug_oct_m
35 use dipole_oct_m
39 use elf_oct_m
43 use forces_oct_m
45 use global_oct_m
46 use grid_oct_m
56 use ions_oct_m
57 use kick_oct_m
62 use lasers_oct_m
63 use lda_u_oct_m
64 use loct_oct_m
65 use mesh_oct_m
68 use mpi_oct_m
73 use output_oct_m
75 use parser_oct_m
76 use pes_oct_m
91 use rdmft_oct_m
93 use scf_oct_m
94 use space_oct_m
98 use stress_oct_m
99 use sort_oct_m
101 use system_oct_m
102 use td_oct_m
105 use v_ks_oct_m
106 use wannier_oct_m, only: wannier_t
108 use xc_oct_m
109 use xc_f03_lib_m
110 use xc_oep_oct_m
114
115 implicit none
116
117 private
118 public :: &
120
123 real(real64), parameter :: ELECTRON_CHARGE = -m_one
124
130 type, extends(system_t) :: electrons_t
131 ! Components are public by default
132 type(electron_space_t) :: space
133 class(ions_t), pointer :: ions => null()
134 type(photons_t), pointer :: photons => null()
135 type(grid_t) :: gr
136 type(states_elec_t) :: st
137 class(v_ks_t), allocatable :: ks
138 type(output_t) :: outp
139 type(multicomm_t) :: mc
140 class(hamiltonian_elec_t), allocatable :: hm
141 class(td_t), allocatable :: td
142 type(current_t) :: current_calculator
143 type(dipole_t) :: dipole
144 class(scf_t), allocatable :: scf
145 type(rdm_t) :: rdm
146
147 type(kpoints_t) :: kpoints
148
149 logical :: generate_epot
150
151 type(states_elec_t) :: st_copy
152
153 ! At the moment this is not treated as an external potential
154 class(lasers_t), pointer :: lasers => null()
155 class(gauge_field_t), pointer :: gfield => null()
156
157 ! List with all the external partners
158 ! This will become a list of interactions in the future
159 type(partner_list_t) :: ext_partners
160
161 !TODO: have a list of self interactions
162 type(xc_interaction_t), pointer :: xc_interaction => null()
163
164 type(dmp_t) :: dmp
165
166 logical :: ions_propagated = .false.
167
168 ! everything related to wannier functions
169 type(wannier_t) :: wannier
170
171 contains
172 procedure :: init_interaction => electrons_init_interaction
173 procedure :: new_algorithm => electrons_new_algorithm
174 procedure :: initialize => electrons_initialize
175 procedure :: do_algorithmic_operation => electrons_do_algorithmic_operation
176 procedure :: is_tolerance_reached => electrons_is_tolerance_reached
177 procedure :: update_quantity => electrons_update_quantity
178 procedure :: init_interaction_as_partner => electrons_init_interaction_as_partner
179 procedure :: copy_quantities_to_interaction => electrons_copy_quantities_to_interaction
180 procedure :: output_start => electrons_output_start
181 procedure :: output_write => electrons_output_write
182 procedure :: output_finish => electrons_output_finish
183 procedure :: process_is_slave => electrons_process_is_slave
184 procedure :: restart_write_data => electrons_restart_write_data
185 procedure :: restart_read_data => electrons_restart_read_data
186 procedure :: update_kinetic_energy => electrons_update_kinetic_energy
187 procedure :: algorithm_start => electrons_algorithm_start
188 procedure :: ground_state_run => electrons_ground_state_run_system
189 final :: electrons_finalize
190 end type electrons_t
191
192 interface electrons_t
193 procedure electrons_constructor
194 end interface electrons_t
196contains
197
202 function electrons_constructor(namespace, grp, calc_mode_id) result(sys)
203 class(electrons_t), pointer :: sys
204 type(namespace_t), intent(in) :: namespace
205 type(mpi_grp_t), intent(in) :: grp
206 integer, optional, intent(in) :: calc_mode_id
208 integer :: iatom
209 integer(int64) :: go_type
210 type(lattice_vectors_t) :: latt_inp
211 logical :: has_photons, variable_cell, cell_dynamics
213 push_sub_with_profile(electrons_constructor)
215 allocate(sys)
216 safe_allocate(sys%ks)
217 safe_allocate(sys%hm)
218 safe_allocate(sys%td)
219 safe_allocate(sys%scf)
220 safe_allocate(sys%ks%oep)
221 safe_allocate(sys%ks%ks_inversion)
222 safe_allocate(sys%ks%sic)
224 sys%namespace = namespace
225
226 call sys%init_parallelization(grp)
228 call messages_obsolete_variable(sys%namespace, 'SystemName')
229
230 sys%space = electron_space_t(sys%namespace)
231 call sys%space%write_info(sys%namespace)
232 if (sys%space%has_mixed_periodicity()) then
233 call messages_experimental('Support for mixed periodicity systems')
234 end if
235
236 sys%ions => ions_t(sys%namespace, grp=sys%grp, latt_inp=latt_inp, shared_namespace=.true.)
237
238 ! We first determine whether the cell is varying or not, as this affects the generation of
239 ! the boundary points (a varying cell needs the full cube stencil, see grid_init_stage_1).
240 variable_cell = .false.
241 if (present(calc_mode_id)) then
242 if (calc_mode_id == option__calculationmode__go) then
243 call parse_variable(sys%namespace, 'GOType', option__gotype__ion_positions, go_type)
244 variable_cell = bitand(go_type, option__gotype__cell_shape) /= 0 &
245 .or. bitand(go_type, option__gotype__cell_volume) /= 0
246 end if
247 end if
248 call parse_variable(sys%namespace, 'CellDynamics', .false., cell_dynamics)
249 variable_cell = variable_cell .or. cell_dynamics
251 call grid_init_stage_1(sys%gr, sys%namespace, sys%space, sys%grp, &
252 sys%ions%symm, latt_inp, sys%ions%natoms, sys%ions%pos, variable_cell)
254 if (sys%space%is_periodic()) then
255 call sys%ions%latt%write_info(sys%namespace)
256 end if
258 ! Sanity check for atomic coordinates
259 do iatom = 1, sys%ions%natoms
260 ! Using the same tolerance of fold_into_cell to avoid problems with mixed periodicities
261 ! as the default tolerance of contains_point is too tight
262 if (.not. sys%gr%box%contains_point(sys%ions%pos(:, iatom), tol=1.0e-6_real64)) then
263 if (sys%space%periodic_dim /= sys%space%dim) then
264 write(message(1), '(a,i5,a)') "Atom ", iatom, " is outside the box."
265 call messages_warning(1, namespace=sys%namespace)
266 end if
267 end if
268 end do
269
270 ! Find possible non-symmorphic symmetries compatible with the real-space grid
271 if (sys%space%dim == 3) then
272 call symmetries_use_compatible_nonsymmorphic(sys%gr%symm, sys%gr%idx%ll, namespace)
273 end if
275 ! we need k-points for periodic systems
276 call kpoints_init(sys%kpoints, sys%namespace, sys%gr%symm, sys%space%dim, sys%space%periodic_dim, sys%ions%latt, &
277 sys%grp)
278
279 call states_elec_init(sys%st, sys%namespace, sys%space, sys%ions%val_charge(), sys%kpoints, calc_mode_id)
280 call sys%st%write_info(sys%namespace)
281
282 ! if independent particles in N dimensions are being used, need to initialize them
283 ! after masses are set to 1 in grid_init_stage_1 -> derivatives_init
284 call sys%st%modelmbparticles%copy_masses(sys%gr%der%masses)
285
286 call elf_init(sys%namespace)
287
288 if (present(calc_mode_id)) then
289 sys%generate_epot = calc_mode_id /= option__calculationmode__dummy
290 else
291 sys%generate_epot = .true.
292 end if
293
294 call sys%dipole%init(sys%space)
295
296 sys%supported_interactions_as_partner = [current_to_mxll_field]
297
298 call sys%quantities%add(quantity_t("wavefunctions", updated_on_demand = .false.))
299 call sys%quantities%add(quantity_t("current", updated_on_demand = .true., parents=["wavefunctions"]))
300 call sys%quantities%add(quantity_t("dipole", updated_on_demand = .true., parents=["wavefunctions"]))
301 call current_init(sys%current_calculator, sys%namespace)
302
303 !%Variable EnablePhotons
304 !%Type logical
305 !%Default no
306 !%Section Hamiltonian
307 !%Description
308 !% This variable can be used to enable photons in several types of calculations.
309 !% It can be used to activate the one-photon OEP formalism.
310 !% In the case of CalculationMode = casida, it enables photon modes as
311 !% described in ACS Photonics 2019, 6, 11, 2757-2778.
312 !% Finally, if set to yes when solving the ferquency-dependent Sternheimer
313 !% equation, the photons are coupled to the electronic subsystem.
314 !%End
315 call messages_obsolete_variable(namespace, 'OEPPtX', 'EnablePhotons')
316 call parse_variable(namespace, 'EnablePhotons', .false., has_photons)
317 if (has_photons) then
318 call messages_experimental("EnablePhotons = yes")
319 sys%photons => photons_t(sys%namespace, sys%grp)
320 else
321 nullify(sys%photons)
322 end if
323
324 call sys%wannier%init_from_input(sys%namespace, sys%kpoints, sys%ions, sys%space, sys%st, sys%gr)
325
327
328 pop_sub_with_profile(electrons_constructor)
329 end function electrons_constructor
330
331 ! ---------------------------------------------------------
332 subroutine electrons_init_interaction(this, interaction)
333 class(electrons_t), target, intent(inout) :: this
334 class(interaction_t), intent(inout) :: interaction
335
336 real(real64) :: dmin
337 integer :: rankmin, depth
338 logical :: mxll_interaction_present
339 logical :: calc_dipole
340
341 push_sub(electrons_init_interactions)
342
343 mxll_interaction_present = .false.
344 select type (interaction)
346 call interaction%init(this%gr, 3)
347 mxll_interaction_present = .true.
348 interaction%type = mxll_field_trans
350 call interaction%init(this%gr, 3)
351 mxll_interaction_present = .true.
353 call interaction%init(this%gr, 3)
354 mxll_interaction_present = .true.
355 class default
356 message(1) = "Trying to initialize an unsupported interaction by the electrons."
357 call messages_fatal(1, namespace=this%namespace)
358 end select
359
360 if (mxll_interaction_present) then
361 calc_dipole = any(this%hm%mxll%coupling_mode == &
363
364 if (calc_dipole) then
365 assert(this%space%periodic_dim == 0)
366 this%hm%mxll%calc_field_dip = .true.
367 this%hm%mxll%center_of_mass(1:3) = this%ions%center_of_mass()
368 this%hm%mxll%center_of_mass_ip = mesh_nearest_point(this%gr, this%hm%mxll%center_of_mass, dmin, rankmin)
369 this%hm%mxll%center_of_mass_rankmin = rankmin
370 end if
371 end if
372
373 ! set interpolation depth for field-transfer interactions
374 select type (interaction)
375 class is (field_transfer_t)
376 ! interpolation depth depends on the propagator
377 select type (algo => this%algo)
378 type is (propagator_exp_mid_t)
379 depth = 3
380 type is (propagator_aetrs_t)
381 depth = 3
382 type is (propagator_bomd_t)
383 depth = 1
384 class default
385 message(1) = "The chosen algorithm does not yet support interaction interpolation"
386 call messages_fatal(1, namespace=this%namespace)
387 end select
388
389 call interaction%init_interpolation(depth, interaction%label)
390 end select
391
392 pop_sub(electrons_init_interactions)
393 end subroutine electrons_init_interaction
394
395 ! ---------------------------------------------------------
396 subroutine electrons_init_parallelization(this)
397 class(electrons_t), intent(inout) :: this
398
399 integer(int64) :: index_range(4)
400 real(real64) :: mesh_global, mesh_local, wfns
401 integer :: idir
402 real(real64) :: spiral_q(3), spiral_q_red(3)
403 type(block_t) :: blk
406
407 ! store the ranges for these two indices (serves as initial guess
408 ! for parallelization strategy)
409 index_range(1) = this%gr%np_global ! Number of points in mesh
410 index_range(2) = this%st%nst ! Number of states
411 index_range(3) = this%st%nik ! Number of k-points
412 index_range(4) = 100000 ! Some large number
413
414 ! create index and domain communicators
415 call multicomm_init(this%mc, this%namespace, this%grp, calc_mode_par, &
416 this%grp%size, index_range, (/ 5000, 1, 1, 1 /))
417
418 call this%ions%partition(this%mc)
419 call kpoints_distribute(this%st, this%mc)
420 call states_elec_distribute_nodes(this%st, this%namespace, this%mc)
421
422
423 if (parse_is_defined(this%namespace, 'TDMomentumTransfer') .or. &
424 parse_is_defined(this%namespace, 'TDReducedMomentumTransfer')) then
425 spiral_q = m_zero
426 if (parse_block(this%namespace, 'TDMomentumTransfer', blk) == 0) then
427 do idir = 1, this%space%dim
428 call parse_block_float(blk, 0, idir - 1, spiral_q(idir))
429 end do
430 else if(parse_block(this%namespace, 'TDReducedMomentumTransfer', blk) == 0) then
431 do idir = 1, this%space%dim
432 call parse_block_float(blk, 0, idir - 1, spiral_q_red(idir))
433 end do
434 call kpoints_to_absolute(this%kpoints%latt, spiral_q_red(1:this%space%dim), spiral_q(1:this%space%dim))
435 end if
436 call parse_block_end(blk)
437 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc, spiral_q)
438 else
439 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
440 end if
441
442 if (this%st%symmetrize_density) then
443 call mesh_check_symmetries(this%gr, this%gr%symm, this%ions%space%periodic_dim)
444 end if
445
446 call output_init(this%outp, this%namespace, this%space, this%st, this%gr, this%st%nst, this%ks)
447 call states_elec_densities_init(this%st, this%gr)
448 call states_elec_exec_init(this%st, this%namespace, this%mc)
449
450 if (associated(this%photons)) then
451 call this%ks%v_ks_photons%set_active(.true.)
452 end if
453
454 call v_ks_init(this%ks, this%namespace, this%gr, this%st, this%ions, this%mc, this%space, &
455 this%kpoints)
456 if (this%ks%theory_level == kohn_sham_dft .or. this%ks%theory_level == generalized_kohn_sham_dft) then
457 this%xc_interaction => xc_interaction_t(this)
458 end if
459
460 ! For the moment the photons are initialized here
461 if (this%ks%v_ks_photons%active()) then
462 call this%ks%v_ks_photons%setup(this%namespace, this%photons%modes, this%gr, this%st, this%ions, &
463 this%mc, this%space, this%ks%xc, this%ks%xc_family, this%ks%oep%level)
464 end if
465
466
467 ! Temporary place for the initialization of the lasers
468 this%lasers => lasers_t(this%namespace)
469 call lasers_parse_external_fields(this%lasers)
470 call lasers_generate_potentials(this%lasers, this%gr, this%space, this%ions%latt)
471 if(this%lasers%no_lasers > 0) then
472 call this%ext_partners%add(this%lasers)
473 call lasers_check_symmetries(this%lasers, this%kpoints)
474 else
475 deallocate(this%lasers)
476 end if
477
478 ! Temporary place for the initialization of the gauge field
479 this%gfield => gauge_field_t(this%namespace, this%ions%latt%rcell_volume)
480 if(gauge_field_is_used(this%gfield)) then
481 call this%ext_partners%add(this%gfield)
482 call gauge_field_check_symmetries(this%gfield, this%kpoints)
483 else
484 deallocate(this%gfield)
485 end if
486
487 call hamiltonian_elec_init(this%hm, this%namespace, this%space, this%gr, this%ions, this%ext_partners, &
488 this%st, this%ks%theory_level, this%ks%xc, this%mc, this%kpoints, &
489 need_exchange = output_need_exchange(this%outp) .or. this%ks%oep%level /= oep_level_none, &
490 xc_photons = this%ks%v_ks_photons%get_xc_photons() )
491
492 ! Fence the spin treatments and theory levels / functionals (meta-GGA, hybrids/HF, PZ-SIC/OEP,
493 ! DFT+U) that are not yet correct for ultrasoft/PAW. This must come after
494 ! hamiltonian_elec_init, which sets st%requires_generalized_overlap.
495 call v_ks_check_generalized_overlap(this%ks, this%st, this%hm, this%namespace)
496
497 ! Fence the requested outputs that are not yet correct for ultrasoft/PAW. This must come after
498 ! hamiltonian_elec_init, which sets st%requires_generalized_overlap.
499 call output_check_generalized_overlap(this%outp, this%st, this%namespace)
500
501 if (this%hm%pcm%run_pcm .and. this%mc%par_strategy /= p_strategy_serial .and. this%mc%par_strategy /= p_strategy_states) then
502 call messages_experimental('Parallel in domain calculations with PCM')
503 end if
504
505 ! Print memory requirements
506 call messages_print_with_emphasis(msg='Approximate memory requirements', namespace=this%namespace)
507
508 mesh_global = mesh_global_memory(this%gr)
509 mesh_local = mesh_local_memory(this%gr)
510
511 call messages_write('Mesh')
512 call messages_new_line()
513 call messages_write(' global :')
514 call messages_write(mesh_global, units = unit_megabytes, fmt = '(f10.1)')
515 call messages_new_line()
516 call messages_write(' local :')
517 call messages_write(mesh_local, units = unit_megabytes, fmt = '(f10.1)')
518 call messages_new_line()
519 call messages_write(' total :')
520 call messages_write(mesh_global + mesh_local, units = unit_megabytes, fmt = '(f10.1)')
521 call messages_new_line()
522 call messages_info(namespace=this%namespace)
523
524 wfns = states_elec_wfns_memory(this%st, this%gr)
525 call messages_write('States')
526 call messages_new_line()
527 call messages_write(' real :')
528 call messages_write(wfns, units = unit_megabytes, fmt = '(f10.1)')
529 call messages_write(' (par_kpoints + par_states + par_domains)')
530 call messages_new_line()
531 call messages_write(' complex :')
532 call messages_write(2.0_8*wfns, units = unit_megabytes, fmt = '(f10.1)')
533 call messages_write(' (par_kpoints + par_states + par_domains)')
534 call messages_new_line()
535 call messages_info(namespace=this%namespace)
536
537 call messages_print_with_emphasis(namespace=this%namespace)
538
539 if (this%generate_epot) then
540 message(1) = "Info: Generating external potential"
541 call messages_info(1, namespace=this%namespace)
542 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
543 this%ext_partners, this%st)
544 message(1) = " done."
545 call messages_info(1, namespace=this%namespace)
546 end if
547
548 if (this%ks%theory_level /= independent_particles) then
549 call poisson_async_init(this%hm%psolver, this%mc)
550 ! slave nodes do not call the calculation routine
551 if (multicomm_is_slave(this%mc)) then
552 !for the moment we only have one type of slave
553 call poisson_slave_work(this%hm%psolver, this%namespace)
554 end if
555 end if
556
557 allocate(this%supported_interactions(0))
558 select case (this%hm%mxll%coupling_mode)
560 this%supported_interactions = [this%supported_interactions, mxll_e_field_to_matter]
562 this%supported_interactions = [this%supported_interactions, mxll_vec_pot_to_matter]
563 if (this%hm%mxll%add_zeeman) then
564 this%supported_interactions = [this%supported_interactions, mxll_b_field_to_matter]
565 end if
567 if (this%hm%mxll%add_electric_dip .or. this%hm%mxll%add_electric_quad) then
568 this%supported_interactions = [this%supported_interactions, mxll_e_field_to_matter]
569 end if
570 if (this%hm%mxll%add_magnetic_dip) then
571 this%supported_interactions = [this%supported_interactions, mxll_b_field_to_matter]
572 end if
574 ! Do not initialize any interaction with Maxwell
575 case default
576 message(1) = "Unknown maxwell-matter coupling"
577 call messages_fatal(1, namespace=this%namespace)
578 end select
579
580 call this%wannier%init_parallelization(this%namespace, this%st, this%ions, this%kpoints)
581
583 end subroutine electrons_init_parallelization
584
585 ! ---------------------------------------------------------
586 subroutine electrons_new_algorithm(this, factory)
587 class(electrons_t), intent(inout) :: this
588 class(algorithm_factory_t), intent(in) :: factory
589
591
592 call system_new_algorithm(this, factory)
593
594 select type (algo => this%algo)
595 class is (propagator_t)
596
597 call td_init(this%td, this%namespace, this%space, this%gr, this%ions, this%st, this%ks, &
598 this%hm, this%ext_partners, this%outp, this%dmp)
599
600 ! this corresponds to the first part of td_init_run
601 call td_allocate_wavefunctions(this%td, this%namespace, this%mc, this%gr, this%ions, this%st, &
602 this%hm, this%space)
603 call td_init_gaugefield(this%td, this%namespace, this%gr, this%st, this%ks, this%hm, &
604 this%ext_partners, this%space)
605
606 class is (minimizer_algorithm_t)
607
608 call electrons_gs_allocate_wavefunctions(this%namespace, this%gr, this%st, this%hm, this%scf, this%ks, &
609 this%ions)
610
611 class default
612 assert(.false.)
613 end select
614
616 end subroutine electrons_new_algorithm
617
618 ! ---------------------------------------------------------
619 subroutine electrons_initialize(this)
620 class(electrons_t), intent(inout) :: this
621
622 push_sub(electrons_initialize)
623
624 if (associated(this%ions)) call this%ions%initialize()
625
626 select type (algo => this%algo)
627 class is (propagator_t)
628 call td_set_from_scratch(this%td, .true.)
629 call td_load_restart_from_gs(this%td, this%namespace, this%space, this%mc, this%gr, &
630 this%ext_partners, this%st, this%ks, this%hm)
631 call this%wannier%init_data_from_file(this%kpoints)
632
633 class is (minimizer_algorithm_t)
634
635 call electrons_gs_initialize(this%namespace, this%scf, this%rdm, this%gr, this%mc, this%st, &
636 this%hm, this%ions, this%ks, this%space, this%ext_partners, fromscratch=.true.)
637 class default
638 assert(.false.)
639 end select
640
641 pop_sub(electrons_initialize)
642 end subroutine electrons_initialize
643
644 ! ---------------------------------------------------------
645 subroutine electrons_algorithm_start(this)
646 class(electrons_t), intent(inout) :: this
647
649
650 call system_algorithm_start(this)
651
652 select type (algo => this%algo)
653 class is (propagator_t)
654
655 ! additional initialization needed for electrons
656 call td_init_with_wavefunctions(this%td, this%namespace, this%space, this%mc, this%gr, this%ions, &
657 this%ext_partners, this%st, this%ks, this%hm, this%outp, this%dmp, td_get_from_scratch(this%td))
659 end select
660
662 end subroutine electrons_algorithm_start
663
664 ! ---------------------------------------------------------
665 logical function electrons_do_algorithmic_operation(this, operation, updated_quantities) result(done)
666 class(electrons_t), intent(inout) :: this
667 class(algorithmic_operation_t), intent(in) :: operation
668 character(len=:), allocatable, intent(out) :: updated_quantities(:)
669
670 logical :: update_energy_
671 type(gauge_field_t), pointer :: gfield
672 real(real64) :: time
673 integer :: iter
674
676 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
677
678 update_energy_ = .true.
679
680 ! kick at t > 0 still missing!
681
682 done = .true.
683 select type (algo => this%algo)
684 class is (propagator_t)
685 time = algo%iteration%value()
686 select case (operation%id)
687 case (aetrs_first_half)
688 ! propagate half of the time step with H(time)
689 call get_fields_from_interaction(this, time)
690 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
691 this%hm, this%ext_partners, time)
692 call propagation_ops_elec_exp_apply(this%td%tr%te, this%namespace, this%st, this%gr, this%hm, m_half*algo%dt)
693
694 case (aetrs_extrapolate)
695 ! Do the extrapolation of the Hamiltonian
696 ! First the extrapolation of the potential
697 call this%hm%ks_pot%interpolation_new(this%td%tr%vks_old, time+algo%dt, algo%dt)
698
699 !Get the potentials from the interpolator
700 call propagation_ops_elec_interpolate_get(this%hm, this%td%tr%vks_old)
701
702 ! Second the ions and gauge field which later on will be treated as extrapolation
703 ! of interactions, but this is not yet possible
704
705 ! move the ions to time t
706 call propagation_ops_elec_move_ions(this%td%tr%propagation_ops_elec, this%gr, this%hm, &
707 this%st, this%namespace, this%space, this%td%ions_dyn, this%ions, this%ext_partners, &
708 this%mc, time+algo%dt, algo%dt)
709
710 !Propagate gauge field
711 gfield => list_get_gauge_field(this%ext_partners)
712 if(associated(gfield)) then
713 call propagation_ops_elec_propagate_gauge_field(this%td%tr%propagation_ops_elec, gfield, &
714 algo%dt, time+algo%dt)
715 end if
716
717 !Update Hamiltonian and current
718 call get_fields_from_interaction(this, time+algo%dt)
719 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
720 this%hm, this%ext_partners, time+algo%dt)
721
722 case (aetrs_second_half)
723 !Do the time propagation for the second half of the time step
724 call propagation_ops_elec_fuse_density_exp_apply(this%td%tr%te, this%namespace, this%st, &
725 this%gr, this%hm, m_half*algo%dt)
726
727 updated_quantities = ["wavefunctions"]
728
729 case (expmid_extrapolate)
730 ! the half step of this propagator screws with the gauge field kick
731 gfield => list_get_gauge_field(this%ext_partners)
732 if(associated(gfield)) then
733 assert(gauge_field_is_propagated(gfield) .eqv. .false.)
734 end if
735
736 ! Do the extrapolation of the Hamiltonian
737 ! First the extrapolation of the potential
738 call this%hm%ks_pot%interpolation_new(this%td%tr%vks_old, time+algo%dt, algo%dt)
739
740 ! get the potentials from the interpolator
741 call this%hm%ks_pot%interpolate_potentials(this%td%tr%vks_old, 3, time+algo%dt, algo%dt, time + algo%dt/m_two)
742
743 ! Second the ions which later on will be treated as extrapolation of interactions,
744 ! but this is not yet possible
745 ! move the ions to the half step
746 call propagation_ops_elec_move_ions(this%td%tr%propagation_ops_elec, this%gr, this%hm, this%st, &
747 this%namespace, this%space, this%td%ions_dyn, this%ions, this%ext_partners, &
748 this%mc, time + m_half*algo%dt, m_half*algo%dt, save_pos=.true.)
749
750 call get_fields_from_interaction(this, time + m_half*algo%dt)
751 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
752 this%hm, this%ext_partners, time + m_half*algo%dt)
753
754 case (expmid_propagate)
755 ! Do the actual propagation step
756 call propagation_ops_elec_fuse_density_exp_apply(this%td%tr%te, this%namespace, this%st, &
757 this%gr, this%hm, algo%dt)
758
759 ! restore to previous time
760 call propagation_ops_elec_restore_ions(this%td%tr%propagation_ops_elec, this%td%ions_dyn, this%ions)
761
762 updated_quantities = ["wavefunctions"]
763
764 case (bomd_start)
765 call scf_init(this%scf, this%namespace, this%gr, this%ions, this%st, this%mc, this%hm, this%space)
766 ! the ions are propagated inside the propagation step already, so no need to do it at the end
767 this%ions_propagated = .true.
768
769 case (verlet_update_pos)
770 ! move the ions to time t
771 call propagation_ops_elec_propagate_ions_and_cell(this%gr, this%hm, this%st, this%namespace, this%space, &
772 this%td%ions_dyn, this%ions, this%mc, time+algo%dt, algo%dt)
773
774 case (bomd_elec_scf)
775 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
776 this%ext_partners, this%st, time = time+algo%dt)
777 ! now calculate the eigenfunctions
778 call scf_run(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
779 this%ext_partners, this%st, this%ks, this%hm, verbosity = verb_compact)
780 ! TODO: Check if this call is realy needed. - NTD
781 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
782 this%ext_partners, this%st, time = time+algo%dt)
783
784 ! update Hamiltonian and eigenvalues (fermi is *not* called)
785 call v_ks_calc(this%ks, this%namespace, this%space, this%hm, this%st, this%ions, this%ext_partners, &
786 calc_eigenval = .true., time = time+algo%dt, calc_energy = .true.)
787
788 ! Get the energies.
789 call energy_calc_total(this%namespace, this%space, this%hm, this%gr, this%st, this%ext_partners, iunit = -1)
790
791 updated_quantities = ["wavefunctions"]
792
793 case (verlet_compute_acc)
794 ! Do nothing, forces are computing in scf_run
795 if (this%td%ions_dyn%cell_relax()) then
796 assert(this%scf%calc_stress)
797 call this%td%ions_dyn%update_stress(this%ions%space, this%st%stress_tensors%total, &
798 this%ions%latt%rlattice, this%ions%latt%rcell_volume)
799 end if
800
801 case (verlet_compute_vel)
802 call ion_dynamics_propagate_vel(this%td%ions_dyn, this%ions)
803 ! TODO: Check if this call is realy needed. - NTD
804 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
805 this%ext_partners, this%st, time = time+algo%dt)
806 call this%ions%update_kinetic_energy()
807
808 case (expmid_start)
809 this%ions_propagated = .false.
810
811 case (aetrs_start)
812 ! the ions are propagated inside the propagation step already, so no need to do it at the end
813 this%ions_propagated = .true.
814
815 case (iteration_done)
817 done = .false.
818
819 case (bomd_finish)
820 call scf_end(this%scf)
821
823 case default
824 done = .false.
825 end select
826
827 class is(minimizer_algorithm_t)
828
829 ! Clocks starts at 0....
830 iter = nint(this%iteration%value()) + 1
831
832 select case(operation%id)
833 case (gs_scf_start)
834 call scf_start(this%scf, this%namespace, this%gr, this%ions, this%st, this%ks, this%hm, this%outp)
835
836 case (gs_scf_iteration)
837
838 call scf_iter(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
839 this%ext_partners, this%st, this%ks, this%hm, iter, outp = this%outp, &
840 restart_dump=this%scf%restart_dump)
841
842 algo%converged = scf_iter_finish(this%scf, this%namespace, this%space, this%gr, this%ions,&
843 this%st, this%ks, this%hm, iter, outp = this%outp)
844
845 updated_quantities = ["wavefunctions"]
846
847 case (gs_scf_finish)
848
849 ! Here iteration is iter-1, as the clock ticked before SCF_FINISH
850 call scf_finish(this%scf, this%namespace, this%space, this%gr, this%ions, &
851 this%ext_partners, this%st, this%ks, this%hm, iter-1, outp = this%outp)
852
853 case default
854 done = .false.
855 end select
856 class default
857 done = .false.
858 end select
859
860 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
863
864 ! ---------------------------------------------------------
865 logical function electrons_is_tolerance_reached(this, tol) result(converged)
866 class(electrons_t), intent(in) :: this
867 real(real64), intent(in) :: tol
868
870
871 converged = .false.
872
875
876 ! ---------------------------------------------------------
877 subroutine electrons_update_quantity(this, label)
878 class(electrons_t), intent(inout) :: this
879 character(len=*), intent(in) :: label
880
881 class(quantity_t), pointer :: quantity
882
884 call profiling_in(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
885
886 quantity => this%quantities%get(label)
887 if(associated(quantity)) then
888 assert(quantity%updated_on_demand)
889 endif
890
891 select case (label)
892 case ("current")
893 call states_elec_allocate_current(this%st, this%space, this%gr)
894 call current_calculate(this%current_calculator, this%namespace, this%gr, &
895 this%hm, this%space, this%st)
896 case ("dipole")
897 call this%dipole%calculate(this%gr, this%ions, this%st)
898 case default
899 message(1) = "Incompatible quantity: "//trim(label)//"."
900 call messages_fatal(1, namespace=this%namespace)
901 end select
902
903 call profiling_out(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
905 end subroutine electrons_update_quantity
906
907 ! ---------------------------------------------------------
908 subroutine electrons_init_interaction_as_partner(partner, interaction)
909 class(electrons_t), intent(in) :: partner
910 class(interaction_surrogate_t), intent(inout) :: interaction
911
913
914 select type (interaction)
916 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
917 class default
918 message(1) = "Unsupported interaction."
919 call messages_fatal(1, namespace=partner%namespace)
920 end select
921
924
925 ! ---------------------------------------------------------
926 subroutine electrons_copy_quantities_to_interaction(partner, interaction)
927 class(electrons_t), intent(inout) :: partner
928 class(interaction_surrogate_t), intent(inout) :: interaction
929
931 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
932
933 select type (interaction)
935 assert(allocated(partner%st%current))
936 ! electric current q_e j, summed over the spin channels
937 interaction%partner_field(:,:) = electron_charge* &
938 sum(partner%st%current(1:partner%gr%np, :, 1:partner%st%d%spin_channels), dim=3)
939 call interaction%do_mapping()
940 class default
941 message(1) = "Unsupported interaction."
942 call messages_fatal(1, namespace=partner%namespace)
943 end select
944
945 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
948
949 ! ---------------------------------------------------------
950 subroutine electrons_output_start(this)
951 class(electrons_t), intent(inout) :: this
952
953 push_sub(electrons_output_start)
954
956 end subroutine electrons_output_start
957
958 ! ---------------------------------------------------------
959 subroutine electrons_output_write(this)
960 class(electrons_t), intent(inout) :: this
961
962 integer :: iter
963
964 push_sub(electrons_output_write)
965 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
966
967 select type (algo => this%algo)
968 class is (propagator_t)
969 iter = this%iteration%counter()
970
971 call td_write_iter(this%td%write_handler, this%namespace, this%space, this%outp, this%gr, &
972 this%st, this%hm, this%ions, this%ext_partners, this%hm%kick, this%ks, algo%dt, iter, this%mc, &
973 this%td%recalculate_gs, this%dmp)
974
975 if (this%outp%anything_now(iter)) then ! output
976 call td_write_output(this%namespace, this%space, this%gr, this%st, this%hm, this%ks, &
977 this%outp, this%ions, this%ext_partners, iter, algo%dt)
978 end if
979 ! This is written as an exception to avoid modifying the args of `td_write_output`
980 ! TODO(Alex) Implement IO registry class
981 call this%wannier%write_iter(this%namespace, this%outp, this%ions, this%kpoints)
982 end select
983
984 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
986 end subroutine electrons_output_write
987
988 ! ---------------------------------------------------------
989 subroutine electrons_output_finish(this)
990 class(electrons_t), intent(inout) :: this
991
993
995 end subroutine electrons_output_finish
996
997 ! ---------------------------------------------------------
998 logical function electrons_process_is_slave(this) result(is_slave)
999 class(electrons_t), intent(in) :: this
1000
1002
1003 is_slave = multicomm_is_slave(this%mc)
1004
1006 end function electrons_process_is_slave
1007
1008 ! ---------------------------------------------------------
1009 subroutine electrons_exec_end_of_timestep_tasks(this, prop)
1010 class(electrons_t), intent(inout) :: this
1011 class(propagator_t), intent(in) :: prop
1012
1013 logical :: stopping
1014 logical :: generate
1015 logical :: update_energy_
1016 integer :: nt
1017 real(real64) :: time
1018 type(gauge_field_t), pointer :: gfield
1019
1021 call profiling_in(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
1023 stopping = .false.
1024
1025 nt = this%td%iter
1026 ! this is the time at the end of the timestep, as required in all routines here
1027 time = prop%dt*nt
1028 update_energy_ = .true.
1029
1030 !Apply mask absorbing boundaries
1031 if (this%hm%abs_boundaries%abtype == mask_absorbing) call zvmask(this%gr, this%hm, this%st)
1032
1033 !Photoelectron stuff
1034 if (this%td%pesv%calc_spm .or. this%td%pesv%calc_mask .or. this%td%pesv%calc_flux) then
1035 call pes_calc(this%td%pesv, this%namespace, this%space, this%gr, this%st, &
1036 prop%dt, nt, this%gr%der, this%hm%kpoints, this%ext_partners, stopping)
1037 end if
1038
1039 ! For BOMD, we do not want the lines below to be executed
1040 select type(prop)
1041 type is(propagator_bomd_t)
1042 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
1044 return
1045 end select
1046
1047 ! The propagation of the ions and the gauge field is currently done here.
1048 ! TODO: this code is to be moved to their own systems at some point
1049 generate = .false.
1050 if (this%td%ions_dyn%is_active()) then
1051 if (.not. this%ions_propagated) then
1052 call propagation_ops_elec_propagate_ions_and_cell(this%gr, this%hm, this%st, this%namespace, this%space, &
1053 this%td%ions_dyn, this%ions, this%mc, abs(nt*prop%dt), this%td%ions_dyn%ionic_scale*prop%dt)
1054 generate = .true.
1055 end if
1056 end if
1057
1058 gfield => list_get_gauge_field(this%ext_partners)
1059 if(associated(gfield)) then
1060 if (gauge_field_is_propagated(gfield) .and. .not. this%ions_propagated) then
1062 end if
1063 end if
1064
1065 if (generate .or. this%ions%has_time_dependent_species()) then
1066 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
1067 this%ext_partners, this%st, time = abs(nt*prop%dt))
1068 end if
1069
1070 call v_ks_calc(this%ks, this%namespace, this%space, this%hm, this%st, this%ions, this%ext_partners, &
1071 calc_eigenval = update_energy_, time = abs(nt*prop%dt), calc_energy = update_energy_)
1072
1073 if (update_energy_) then
1074 call energy_calc_total(this%namespace, this%space, this%hm, this%gr, this%st, this%ext_partners, iunit = -1)
1075 end if
1076
1077 ! Recalculate forces, update velocities...
1078 if (this%td%ions_dyn%ions_move() .or. this%outp%what(option__output__forces) &
1079 .or. this%td%write_handler%out(out_separate_forces)%write) then
1080 call forces_calculate(this%gr, this%namespace, this%ions, this%hm, this%ext_partners, &
1081 this%st, this%ks, t = abs(nt*prop%dt), dt = prop%dt)
1082 end if
1083
1084 if (this%td%ions_dyn%cell_relax() .or. this%outp%what(option__output__stress)) then
1085 call stress_calculate(this%namespace, this%gr, this%hm, this%st, this%ions, this%ks, this%ext_partners)
1086 end if
1087
1088 if(this%td%ions_dyn%is_active()) then
1089 call ion_dynamics_propagate_vel(this%td%ions_dyn, this%ions, atoms_moved = generate)
1090 call this%ions%update_kinetic_energy()
1091 end if
1092
1093 if(associated(gfield)) then
1094 if(gauge_field_is_propagated(gfield)) then
1095 call gauge_field_get_force(gfield, this%gr, this%st%d%spin_channels, this%st%current, this%ks%xc%lrc)
1097 end if
1098 end if
1099
1100 !We update the occupation matrices
1101 call lda_u_update_occ_matrices(this%hm%lda_u, this%namespace, this%gr, this%st, this%hm%phase, this%hm%energy, &
1102 this%hm%aug_overlap)
1103
1104 !Update the wannier matrices
1105 call this%wannier%update_matrices(nt, this%namespace, this%gr, this%space, this%st, this%kpoints, &
1106 this%hm, prop%dt)
1107
1108 ! this is needed to be compatible with the code in td_*
1109 this%td%iter = this%td%iter + 1
1110
1111 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
1114
1115 ! ---------------------------------------------------------
1116 subroutine electrons_restart_write_data(this)
1117 class(electrons_t), intent(inout) :: this
1118
1119 integer :: ierr
1120
1122 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
1123
1124 select type (algo => this%algo)
1125 class is (propagator_t)
1126 call td_write_data(this%td%write_handler)
1127 call td_dump(this%td, this%namespace, this%space, this%gr, this%st, this%hm, &
1128 this%ks, this%ext_partners, this%iteration%counter(), ierr)
1129 if (ierr /= 0) then
1130 message(1) = "Unable to write time-dependent restart information."
1131 call messages_warning(1, namespace=this%namespace)
1132 end if
1133
1134 ! TODO: this is here because of legacy reasons and should be moved to the output framework
1135 call pes_output(this%td%pesv, this%namespace, this%space, this%gr, this%st, this%iteration%counter(), &
1136 this%outp, algo%dt, this%ions)
1137
1138 if (this%wannier%options%td_method /= td_wannier_method_none) then
1139 call this%wannier%restart_write_data(this%namespace, this%mc, this%gr)
1140 end if
1141 end select
1142
1143 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
1145 end subroutine electrons_restart_write_data
1146
1147 ! ---------------------------------------------------------
1148 ! this function returns true if restart data could be read
1149 logical function electrons_restart_read_data(this)
1150 class(electrons_t), intent(inout) :: this
1151
1152 logical :: from_scratch
1153
1155 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
1156
1157 select type (algo => this%algo)
1158 class is (propagator_t)
1159 from_scratch = .false.
1160 call td_load_restart_from_td(this%td, this%namespace, this%space, this%mc, this%gr, &
1161 this%ext_partners, this%st, this%ks, this%hm, from_scratch)
1162
1163 if (.not. from_scratch .and. this%wannier%options%td_method /= td_wannier_method_none) then
1164 call this%wannier%restart_read_data(this%namespace, this%mc, this%gr)
1165 end if
1166
1167 call td_set_from_scratch(this%td, from_scratch)
1168
1169 class is (minimizer_algorithm_t)
1170 from_scratch = .false.
1171 call electrons_gs_load_from_restart(this%namespace, this%scf, this%gr, this%mc, this%st, this%hm, &
1172 this%ks, this%space, this%ions, this%ext_partners,from_scratch)
1173
1174 ! electrons_gs_initialize still knows about fromScratch.
1175 assert(.false.)
1176 end select
1177
1178 if (from_scratch) then
1179 ! restart data could not be loaded
1181 else
1182 ! restart data could be loaded
1184 end if
1185
1186 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
1189
1190 !----------------------------------------------------------
1191 subroutine electrons_update_kinetic_energy(this)
1192 class(electrons_t), intent(inout) :: this
1193
1195
1196 if (states_are_real(this%st)) then
1197 this%kinetic_energy = denergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1198 else
1199 this%kinetic_energy = zenergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1200 end if
1201
1203
1204 end subroutine electrons_update_kinetic_energy
1205
1206 ! ---------------------------------------------------------
1207 subroutine get_fields_from_interaction(this, time)
1208 class(electrons_t), intent(inout) :: this
1209 real(real64), intent(in) :: time
1210
1211 type(interaction_iterator_t) :: iter
1212 real(real64), allocatable :: field_tmp(:, :)
1213
1215
1216 if (this%hm%mxll%coupling_mode == no_maxwell_coupling) then
1218 return
1219 end if
1220
1221 assert(this%gr%box%dim == 3)
1222
1223 safe_allocate(field_tmp(1:this%gr%np, 1:this%gr%box%dim))
1224 this%hm%mxll%e_field = m_zero
1225 this%hm%mxll%b_field = m_zero
1226 this%hm%mxll%vec_pot = m_zero
1227
1228 ! interpolate field from interaction
1229 call iter%start(this%interactions)
1230 do while (iter%has_next())
1231 select type (interaction => iter%get_next())
1232 class is (mxll_e_field_to_matter_t)
1233 call interaction%interpolate(time, field_tmp)
1234 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%e_field)
1235 class is (mxll_vec_pot_to_matter_t)
1236 call interaction%interpolate(time, field_tmp)
1237 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%vec_pot)
1238 class is (mxll_b_field_to_matter_t)
1239 call interaction%interpolate(time, field_tmp)
1240 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%b_field)
1241 end select
1242 end do
1243
1244 safe_deallocate_a(field_tmp)
1246
1247 end subroutine get_fields_from_interaction
1248
1249
1251 subroutine electrons_ground_state_run_system(sys, from_scratch)
1252 class(electrons_t), intent(inout) :: sys
1253 logical, intent(inout) :: from_scratch
1254
1256
1257 call electrons_ground_state_run(sys%namespace, sys%mc, sys%gr, sys%ions, &
1258 sys%ext_partners, sys%st, sys%ks, sys%hm, sys%outp, sys%space, from_scratch)
1259
1261
1264
1265 subroutine electrons_finalize(sys)
1266 type(electrons_t), intent(inout) :: sys
1267
1268 type(partner_iterator_t) :: iter
1269 class(interaction_partner_t), pointer :: partner
1270
1271 push_sub(electrons_finalize)
1272
1273 if (associated(sys%algo)) then
1274 select type (algo => sys%algo)
1275 class is (propagator_t)
1276 call td_end_run(sys%td, sys%st, sys%hm, sys%dmp)
1277 call td_end(sys%td)
1278 class is(minimizer_algorithm_t)
1279 call electrons_gs_cleanup(sys%ks, sys%scf, sys%rdm, sys%st, sys%hm)
1280 end select
1281 end if
1282
1283 if (sys%ks%theory_level /= independent_particles) then
1284 call poisson_async_end(sys%hm%psolver, sys%mc)
1285 end if
1286
1287 call iter%start(sys%ext_partners)
1288 do while (iter%has_next())
1289 partner => iter%get_next()
1290 safe_deallocate_p(partner)
1291 end do
1292 call sys%ext_partners%empty()
1293
1294 safe_deallocate_p(sys%xc_interaction)
1295
1296 call hamiltonian_elec_end(sys%hm)
1297
1298 nullify(sys%gfield)
1299 nullify(sys%lasers)
1300
1301 call multicomm_end(sys%mc)
1302
1303 call sys%dipole%end()
1304
1305 call v_ks_end(sys%ks)
1306
1307 call states_elec_end(sys%st)
1308
1309 deallocate(sys%ions)
1310 safe_deallocate_p(sys%photons)
1311
1312 call kpoints_end(sys%kpoints)
1313
1314 call grid_end(sys%gr)
1315
1316 call system_end(sys)
1317
1318 safe_deallocate_a(sys%ks%oep)
1319 safe_deallocate_a(sys%ks%ks_inversion)
1320 safe_deallocate_a(sys%ks%sic)
1321 safe_deallocate_a(sys%ks)
1322 safe_deallocate_a(sys%hm)
1323 safe_deallocate_a(sys%td)
1324 safe_deallocate_a(sys%scf)
1325
1326 pop_sub(electrons_finalize)
1327 end subroutine electrons_finalize
1328
1329
1330end module electrons_oct_m
1331
1332!! Local Variables:
1333!! mode: f90
1334!! coding: utf-8
1335!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:171
integer, parameter, public mask_absorbing
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:120
character(len=algo_label_len), parameter, public iteration_done
Definition: algorithm.F90:151
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_serial
single domain, all states, k-points on a single processor
integer, parameter, public p_strategy_states
parallelization in states
subroutine, public current_calculate(this, namespace, gr, hm, space, st)
Compute total electronic current density.
Definition: current.F90:352
subroutine, public current_init(this, namespace)
Definition: current.F90:160
This module implements a calculator for the density and defines related functions.
Definition: density.F90:99
This modules implements the dipole moment of the matter system.
Definition: dipole.F90:87
A set of subroutines for performing the parts of a ground state calculation with an electrons system....
subroutine, public electrons_ground_state_run(namespace, mc, gr, ions, ext_partners, st, ks, hm, outp, space, fromScratch)
Run a ground state calculation for a system of electrons.
subroutine, public electrons_gs_allocate_wavefunctions(namespace, gr, st, hm, scf, ks, ions)
subroutine, public electrons_gs_initialize(namespace, scf, rdm, gr, mc, st, hm, ions, ks, space, ext_partners, fromScratch)
subroutine, public electrons_gs_load_from_restart(namespace, scf, gr, mc, st, hm, ks, space, ions, ext_partners, fromScratch)
subroutine, public electrons_gs_cleanup(ks, scf, rdm, st, hm)
subroutine electrons_initialize(this)
Definition: electrons.F90:692
logical function electrons_restart_read_data(this)
Definition: electrons.F90:1222
logical function electrons_process_is_slave(this)
Definition: electrons.F90:1071
subroutine electrons_init_interaction(this, interaction)
Definition: electrons.F90:405
subroutine electrons_finalize(sys)
Definition: electrons.F90:1338
subroutine electrons_exec_end_of_timestep_tasks(this, prop)
Definition: electrons.F90:1082
logical function electrons_do_algorithmic_operation(this, operation, updated_quantities)
Definition: electrons.F90:738
subroutine electrons_new_algorithm(this, factory)
Definition: electrons.F90:659
subroutine electrons_output_write(this)
Definition: electrons.F90:1032
subroutine get_fields_from_interaction(this, time)
Definition: electrons.F90:1280
subroutine electrons_algorithm_start(this)
Definition: electrons.F90:718
subroutine electrons_output_finish(this)
Definition: electrons.F90:1062
subroutine electrons_output_start(this)
Definition: electrons.F90:1023
subroutine electrons_init_parallelization(this)
Definition: electrons.F90:469
subroutine electrons_init_interaction_as_partner(partner, interaction)
Definition: electrons.F90:981
subroutine electrons_ground_state_run_system(sys, from_scratch)
Run a ground state calculation for a system of electrons.
Definition: electrons.F90:1324
subroutine electrons_update_kinetic_energy(this)
Definition: electrons.F90:1264
logical function electrons_is_tolerance_reached(this, tol)
Definition: electrons.F90:938
class(electrons_t) function, pointer electrons_constructor(namespace, grp, calc_mode_id)
@ brief Instantiate an instance of an electrons system
Definition: electrons.F90:275
subroutine electrons_copy_quantities_to_interaction(partner, interaction)
Definition: electrons.F90:999
subroutine electrons_restart_write_data(this)
Definition: electrons.F90:1189
subroutine electrons_update_quantity(this, label)
Definition: electrons.F90:950
subroutine, public elf_init(namespace)
Definition: elf.F90:123
subroutine, public energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
This subroutine calculates the total energy of the system. Basically, it adds up the KS eigenvalues,...
real(real64) function, public zenergy_calc_electronic(namespace, hm, der, st, terms)
real(real64) function, public denergy_calc_electronic(namespace, hm, der, st, terms)
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
This module implements the field transfer.
subroutine, public forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, vhxc_old, t, dt)
Definition: forces.F90:319
subroutine, public gauge_field_get_force(this, gr, spin_channels, current, lrc)
subroutine, public gauge_field_do_algorithmic_operation(this, operation, dt, time)
subroutine, public gauge_field_check_symmetries(this, kpoints)
logical pure function, public gauge_field_is_propagated(this)
logical pure function, public gauge_field_is_used(this)
real(real64), parameter, public m_two
Definition: global.F90:175
real(real64), parameter, public m_zero
Definition: global.F90:173
integer, parameter, public independent_particles
Theory level.
Definition: global.F90:223
integer, parameter, public generalized_kohn_sham_dft
Definition: global.F90:223
integer, parameter, public kohn_sham_dft
Definition: global.F90:223
real(real64), parameter, public m_half
Definition: global.F90:179
real(real64), parameter, public m_one
Definition: global.F90:174
This module implements the underlying real-space grid.
Definition: grid.F90:96
subroutine, public grid_init_stage_1(gr, namespace, space, grp, symm, latt, n_sites, site_position, variable_cell)
First stage of the grid initialization.
Definition: grid.F90:174
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
Definition: grid.F90:460
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:487
integer, parameter, public term_kinetic
subroutine, public zvmask(mesh, hm, st)
subroutine, public hamiltonian_elec_end(hm)
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
subroutine, public hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, mc, kpoints, need_exchange, xc_photons)
integer, parameter, public mxll_vec_pot_to_matter
integer, parameter, public mxll_b_field_to_matter
integer, parameter, public mxll_e_field_to_matter
integer, parameter, public current_to_mxll_field
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
This module defines classes and functions for interaction partners.
subroutine, public ion_dynamics_propagate_vel(this, ions, atoms_moved)
subroutine, public kpoints_end(this)
Definition: kpoints.F90:1045
subroutine, public kpoints_init(this, namespace, symm, dim, periodic_dim, latt, grp)
Definition: kpoints.F90:396
subroutine, public kpoints_to_absolute(latt, kin, kout)
Definition: kpoints.F90:1124
A module to handle KS potential, without the external potential.
subroutine, public lasers_check_symmetries(this, kpoints)
Definition: lasers.F90:535
subroutine, public lasers_parse_external_fields(this)
Definition: lasers.F90:224
subroutine, public lasers_generate_potentials(this, mesh, space, latt)
Definition: lasers.F90:423
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy, aug_overlap)
Definition: lda_u.F90:915
System information (time, memory, sysname)
Definition: loct.F90:94
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:97
subroutine, public mesh_check_symmetries(mesh, symm, periodic_dim)
Definition: mesh.F90:821
integer function, public mesh_nearest_point(mesh, pos, dmin, rankmin)
Returns the index of the point which is nearest to a given vector position pos.
Definition: mesh.F90:368
real(real64) pure function, public mesh_global_memory(mesh)
Definition: mesh.F90:777
real(real64) pure function, public mesh_local_memory(mesh)
Definition: mesh.F90:788
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:878
character(len=512), private msg
Definition: messages.F90:143
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:501
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:980
subroutine, public messages_new_line()
Definition: messages.F90:1069
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:138
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:386
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1020
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:570
This module implements the basic minimizer framework.
character(len=algo_label_len), parameter, public gs_scf_start
character(len=algo_label_len), parameter, public gs_scf_finish
character(len=algo_label_len), parameter, public gs_scf_iteration
general module for modelmb particles
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:124
subroutine, public multicomm_end(mc)
Definition: multicomm.F90:683
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_processes, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:250
logical pure function, public multicomm_is_slave(this)
Definition: multicomm.F90:823
integer, parameter, public length_gauge_dipole
integer, parameter, public no_maxwell_coupling
integer, parameter, public velocity_gauge_dipole
integer, parameter, public multipolar_expansion
integer, parameter, public full_minimal_coupling
Maxwell-field-to-matter interactions.
integer, parameter, public mxll_field_trans
this module contains the low-level part of the output system
Definition: output_low.F90:94
this module contains the output system
Definition: output.F90:94
logical function, public output_need_exchange(outp)
Definition: output.F90:881
subroutine, public output_init(outp, namespace, space, st, gr, nst, ks)
Definition: output.F90:185
subroutine, public output_check_generalized_overlap(outp, st, namespace)
Fence the requested outputs that are not yet correct with a generalized overlap.
Definition: output.F90:465
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:440
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:600
subroutine, public pes_calc(pes, namespace, space, mesh, st, dt, iter, der, kpoints, ext_partners, stopping)
Definition: pes.F90:248
subroutine, public pes_output(pes, namespace, space, gr, st, iter, outp, dt, ions)
Definition: pes.F90:274
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1113
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1141
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1125
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:122
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:672
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:604
subroutine, public propagation_ops_elec_restore_ions(wo, ions_dyn, ions)
subroutine, public propagation_ops_elec_propagate_gauge_field(wo, gfield, dt, time, save_gf)
subroutine, public propagation_ops_elec_propagate_ions_and_cell(gr, hm, st, namespace, space, ions_dyn, ions, mc, time, dt_ions)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
subroutine, public propagation_ops_elec_fuse_density_exp_apply(te, namespace, st, gr, hm, dt, dt2, op, st_td)
Apply to all states, and accumulate the density in the same pass.
subroutine, public propagation_ops_elec_interpolate_get(hm, vks_old)
subroutine, public propagation_ops_elec_move_ions(wo, gr, hm, st, namespace, space, ions_dyn, ions, ext_partners, mc, time, dt, save_pos)
subroutine, public propagation_ops_elec_exp_apply(te, namespace, st, mesh, hm, dt, op)
character(len=algo_label_len), parameter, public aetrs_start
character(len=algo_label_len), parameter, public aetrs_finish
character(len=algo_label_len), parameter, public aetrs_extrapolate
character(len=algo_label_len), parameter, public aetrs_first_half
character(len=algo_label_len), parameter, public aetrs_second_half
character(len=algo_label_len), parameter, public bomd_start
character(len=algo_label_len), parameter, public bomd_elec_scf
character(len=algo_label_len), parameter, public bomd_finish
character(len=algo_label_len), parameter, public expmid_extrapolate
character(len=algo_label_len), parameter, public expmid_finish
character(len=algo_label_len), parameter, public expmid_start
character(len=algo_label_len), parameter, public expmid_propagate
This module implements the basic propagator framework.
Definition: propagator.F90:96
character(len=30), parameter, public verlet_compute_acc
type(algorithmic_operation_t), parameter, public op_verlet_compute_acc
character(len=30), parameter, public verlet_update_pos
type(algorithmic_operation_t), parameter, public op_verlet_compute_vel
character(len=30), parameter, public verlet_compute_vel
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:117
Implementation details for regridding.
Definition: regridding.F90:149
subroutine, public scf_finish(scf, namespace, space, gr, ions, ext_partners, st, ks, hm, iter, outp)
Definition: scf.F90:1309
subroutine, public scf_start(scf, namespace, gr, ions, st, ks, hm, outp, verbosity)
Preparation of the SCF cycle.
Definition: scf.F90:690
integer, parameter, public verb_compact
Definition: scf.F90:183
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:237
subroutine, public scf_end(scf)
Definition: scf.F90:554
subroutine, public scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, verbosity, iters_done, restart_dump)
Legacy version of the SCF code.
Definition: scf.F90:835
subroutine, public scf_iter(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, iter, outp, restart_dump)
Definition: scf.F90:881
logical function, public scf_iter_finish(scf, namespace, space, gr, ions, st, ks, hm, iter, outp, iters_done)
Definition: scf.F90:1230
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:96
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
real(real64) function, public states_elec_wfns_memory(st, mesh)
return the memory usage of a states_elec_t object
subroutine, public states_elec_distribute_nodes(st, namespace, mc)
Distribute states over the processes for states parallelization.
subroutine, public states_elec_densities_init(st, gr)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public kpoints_distribute(this, mc)
distribute k-points over the nodes in the corresponding communicator
subroutine, public states_elec_exec_init(st, namespace, mc)
Further initializations.
subroutine, public states_elec_init(st, namespace, space, valence_charge, kpoints, calc_mode_id)
Initialize a new states_elec_t object.
subroutine, public states_elec_allocate_current(st, space, mesh)
This module implements the calculation of the stress tensor.
Definition: stress.F90:97
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
Definition: stress.F90:167
subroutine, public symmetries_use_compatible_nonsymmorphic(this, ll, namespace)
Detect if some non-symmorphic operations are compatible with the real-space grid If yes,...
Definition: symmetries.F90:810
This module implements the abstract system type.
Definition: system.F90:97
subroutine, public system_algorithm_start(this)
Definition: system.F90:1000
subroutine, public system_end(this)
Definition: system.F90:1129
subroutine, public system_new_algorithm(this, factory)
Definition: system.F90:925
Definition: td.F90:93
subroutine, public td_init_with_wavefunctions(td, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, dmp, from_scratch)
Definition: td.F90:910
subroutine, public td_end(td)
Definition: td.F90:634
subroutine, public td_load_restart_from_gs(td, namespace, space, mc, gr, ext_partners, st, ks, hm)
Definition: td.F90:1233
subroutine, public td_allocate_wavefunctions(td, namespace, mc, gr, ions, st, hm, space)
Definition: td.F90:569
subroutine, public td_init(td, namespace, space, gr, ions, st, ks, hm, ext_partners, outp, dmp)
Definition: td.F90:217
logical function, public td_get_from_scratch(td)
Definition: td.F90:1570
subroutine, public td_set_from_scratch(td, from_scratch)
Definition: td.F90:1581
subroutine, public td_dump(td, namespace, space, gr, st, hm, ks, ext_partners, iter, ierr)
Definition: td.F90:1374
subroutine, public td_init_gaugefield(td, namespace, gr, st, ks, hm, ext_partners, space)
Definition: td.F90:603
subroutine, public td_load_restart_from_td(td, namespace, space, mc, gr, ext_partners, st, ks, hm, from_scratch)
Definition: td.F90:1197
subroutine, public td_end_run(td, st, hm, dmp)
Definition: td.F90:649
subroutine, public td_write_iter(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, kick, ks, dt, iter, mc, recalculate_gs, dmp)
Definition: td_write.F90:1076
subroutine, public td_write_output(namespace, space, gr, st, hm, ks, outp, ions, ext_partners, iter, dt)
Definition: td_write.F90:1295
subroutine, public td_write_data(writ)
Definition: td_write.F90:1261
integer, parameter, public out_separate_forces
Definition: td_write.F90:187
This module defines the unit system, used for input and output.
type(unit_t), public unit_megabytes
For large amounts of data (natural code units are bytes)
subroutine, public v_ks_end(ks)
Definition: v_ks.F90:575
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:769
subroutine, public v_ks_check_generalized_overlap(ks, st, hm, namespace)
Fence the spin treatments and theory levels / functionals that are not yet correct for ultrasoft/PAW.
Definition: v_ks.F90:662
subroutine, public v_ks_init(ks, namespace, gr, st, ions, mc, space, kpoints)
Definition: v_ks.F90:231
Wannier module.
Definition: wannier.F90:97
Wannier options module.
integer, parameter, public td_wannier_method_none
Definition: xc.F90:97
integer, parameter, public oep_level_none
the OEP levels
Definition: xc_oep.F90:150
Abstract class for the algorithm factories.
Descriptor of one algorithmic operation.
Definition: algorithm.F90:142
Class to transfer a current to a Maxwell field.
Extension of space that contains the knowledge of the spin dimension.
Class describing the electron system.
Definition: electrons.F90:202
class defining the field_transfer interaction
These class extend the list and list iterator to make an interaction list.
abstract interaction class
abstract class for general interaction partners
surrogate interaction class to avoid circular dependencies between modules.
Abstract class implementing minimizers.
This is defined even when running serial.
Definition: mpi.F90:121
class to transfer a Maxwell B field to a matter system
class to transfer a Maxwell electric field to a medium
class to transfer a Maxwell vector potential to a medium
Implements a propagator for Approximate ETRS.
Implements a propagator for Born-Oppenheimer molecular dynamics.
Implements the explicit exponential midpoint propagator (without predictor-corrector)
Abstract class implementing propagators.
Definition: propagator.F90:121
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Definition: quantity.F90:150
Abstract class for systems.
Definition: system.F90:152
Main object containing all Wannier-related data and methods.
Definition: wannier.F90:132
int true(void)