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
38 use elf_oct_m
42 use forces_oct_m
44 use global_oct_m
45 use grid_oct_m
55 use ions_oct_m
56 use kick_oct_m
60 use lasers_oct_m
61 use lda_u_oct_m
62 use loct_oct_m
63 use mesh_oct_m
66 use mpi_oct_m
73 use output_oct_m
75 use parser_oct_m
76 use pes_oct_m
92 use rdmft_oct_m
94 use scf_oct_m
95 use space_oct_m
99 use stress_oct_m
100 use sort_oct_m
101 use system_oct_m
102 use td_oct_m
105 use v_ks_oct_m
106 use xc_oct_m
107 use xc_f03_lib_m
108 use xc_oep_oct_m
112
113 implicit none
114
115 private
116 public :: &
118
119
125 type, extends(system_t) :: electrons_t
126 ! Components are public by default
127 type(electron_space_t) :: space
128 class(ions_t), pointer :: ions => null()
129 type(photons_t), pointer :: photons => null()
130 type(grid_t) :: gr
131 type(states_elec_t) :: st
132 type(v_ks_t) :: ks
133 type(output_t) :: outp
134 type(multicomm_t) :: mc
135 type(hamiltonian_elec_t) :: hm
136 type(td_t) :: td
137 type(current_t) :: current_calculator
138 type(dipole_t) :: dipole
139 type(scf_t) :: scf
140 type(rdm_t) :: rdm
141
142 type(kpoints_t) :: kpoints
143
144 logical :: generate_epot
145
146 type(states_elec_t) :: st_copy
147
148 ! At the moment this is not treated as an external potential
149 class(lasers_t), pointer :: lasers => null()
150 class(gauge_field_t), pointer :: gfield => null()
151
152 ! List with all the external partners
153 ! This will become a list of interactions in the future
154 type(partner_list_t) :: ext_partners
155
156 !TODO: have a list of self interactions
157 type(xc_interaction_t), pointer :: xc_interaction => null()
158
159 logical :: ions_propagated = .false.
160 contains
161 procedure :: init_interaction => electrons_init_interaction
162 procedure :: init_parallelization => electrons_init_parallelization
163 procedure :: new_algorithm => electrons_new_algorithm
164 procedure :: initialize => electrons_initialize
165 procedure :: do_algorithmic_operation => electrons_do_algorithmic_operation
166 procedure :: is_tolerance_reached => electrons_is_tolerance_reached
167 procedure :: update_quantity => electrons_update_quantity
168 procedure :: init_interaction_as_partner => electrons_init_interaction_as_partner
169 procedure :: copy_quantities_to_interaction => electrons_copy_quantities_to_interaction
170 procedure :: output_start => electrons_output_start
171 procedure :: output_write => electrons_output_write
172 procedure :: output_finish => electrons_output_finish
173 procedure :: process_is_slave => electrons_process_is_slave
174 procedure :: restart_write_data => electrons_restart_write_data
175 procedure :: restart_read_data => electrons_restart_read_data
176 procedure :: update_kinetic_energy => electrons_update_kinetic_energy
177 procedure :: algorithm_start => electrons_algorithm_start
178 final :: electrons_finalize
179 end type electrons_t
180
181 interface electrons_t
182 procedure electrons_constructor
183 end interface electrons_t
184
185contains
186
187 !----------------------------------------------------------
188 function electrons_constructor(namespace, generate_epot) result(sys)
189 class(electrons_t), pointer :: sys
190 type(namespace_t), intent(in) :: namespace
191 logical, optional, intent(in) :: generate_epot
192
193 integer :: iatom
194 type(lattice_vectors_t) :: latt_inp
195 logical :: has_photons
196
197 push_sub_with_profile(electrons_constructor)
198
199 allocate(sys)
200
201 sys%namespace = namespace
202
203 call messages_obsolete_variable(sys%namespace, 'SystemName')
204
205 sys%space = electron_space_t(sys%namespace)
206 call sys%space%write_info(sys%namespace)
207 if (sys%space%has_mixed_periodicity()) then
208 call messages_experimental('Support for mixed periodicity systems')
209 end if
210
211 sys%ions => ions_t(sys%namespace, latt_inp=latt_inp)
212
213 call grid_init_stage_1(sys%gr, sys%namespace, sys%space, sys%ions%symm, latt_inp, sys%ions%natoms, sys%ions%pos)
214
215 if (sys%space%is_periodic()) then
216 call sys%ions%latt%write_info(sys%namespace)
217 end if
219 ! Sanity check for atomic coordinates
220 do iatom = 1, sys%ions%natoms
221 if (.not. sys%gr%box%contains_point(sys%ions%pos(:, iatom))) then
222 if (sys%space%periodic_dim /= sys%space%dim) then
223 ! FIXME: This could fail for partial periodicity systems
224 ! because contains_point is too strict with atoms close to
225 ! the upper boundary to the cell.
226 write(message(1), '(a,i5,a)') "Atom ", iatom, " is outside the box."
227 call messages_warning(1, namespace=sys%namespace)
228 end if
229 end if
230 end do
232 ! we need k-points for periodic systems
233 call kpoints_init(sys%kpoints, sys%namespace, sys%gr%symm, sys%space%dim, sys%space%periodic_dim, sys%ions%latt)
234
235 call states_elec_init(sys%st, sys%namespace, sys%space, sys%ions%val_charge(), sys%kpoints)
236 call sys%st%write_info(sys%namespace)
238 ! if independent particles in N dimensions are being used, need to initialize them
239 ! after masses are set to 1 in grid_init_stage_1 -> derivatives_init
240 call sys%st%modelmbparticles%copy_masses(sys%gr%der%masses)
241
242 call elf_init(sys%namespace)
244 sys%generate_epot = optional_default(generate_epot, .true.)
245
246 call sys%dipole%init(sys%space)
248 sys%supported_interactions_as_partner = [current_to_mxll_field]
249 sys%quantities(current)%updated_on_demand = .true.
250 sys%quantities(dipole)%updated_on_demand = .true.
251 call current_init(sys%current_calculator, sys%namespace)
253 !%Variable EnablePhotons
254 !%Type logical
255 !%Default no
256 !%Section Hamiltonian
257 !%Description
258 !% This variable can be used to enable photons in several types of calculations.
259 !% It can be used to activate the one-photon OEP formalism.
260 !% In the case of CalculationMode = casida, it enables photon modes as
261 !% described in ACS Photonics 2019, 6, 11, 2757-2778.
262 !% Finally, if set to yes when solving the ferquency-dependent Sternheimer
263 !% equation, the photons are coupled to the electronic subsystem.
264 !%End
265 call messages_obsolete_variable(namespace, 'OEPPtX', 'EnablePhotons')
266 call parse_variable(namespace, 'EnablePhotons', .false., has_photons)
267 if (has_photons) then
268 call messages_experimental("EnablePhotons = yes")
269 sys%photons => photons_t(sys%namespace)
270 else
271 nullify(sys%photons)
272 end if
273
274 pop_sub_with_profile(electrons_constructor)
275 end function electrons_constructor
276
277 ! ---------------------------------------------------------
278 subroutine electrons_init_interaction(this, interaction)
279 class(electrons_t), target, intent(inout) :: this
280 class(interaction_t), intent(inout) :: interaction
282 real(real64) :: dmin
283 integer :: rankmin, depth
284 logical :: mxll_interaction_present = .false.
285 logical :: calc_dipole
286
287 push_sub(electrons_init_interactions)
288
289 select type (interaction)
291 call interaction%init(this%gr, 3)
292 mxll_interaction_present = .true.
293 interaction%type = mxll_field_trans
295 call interaction%init(this%gr, 3)
296 mxll_interaction_present = .true.
298 call interaction%init(this%gr, 3)
299 mxll_interaction_present = .true.
300 class default
301 message(1) = "Trying to initialize an unsupported interaction by the electrons."
302 call messages_fatal(1, namespace=this%namespace)
303 end select
304
305 if (mxll_interaction_present) then
306 calc_dipole = any(this%hm%mxll%coupling_mode == &
308
309 if (calc_dipole) then
310 assert(this%space%periodic_dim == 0)
311 this%hm%mxll%calc_field_dip = .true.
312 this%hm%mxll%center_of_mass(1:3) = this%ions%center_of_mass()
313 this%hm%mxll%center_of_mass_ip = mesh_nearest_point(this%gr, this%hm%mxll%center_of_mass, dmin, rankmin)
314 this%hm%mxll%center_of_mass_rankmin = rankmin
315 end if
316 end if
317
318 ! set interpolation depth for field-transfer interactions
319 select type (interaction)
320 class is (field_transfer_t)
321 ! interpolation depth depends on the propagator
322 select type (algo => this%algo)
323 type is (propagator_exp_mid_t)
324 depth = 3
325 type is (propagator_aetrs_t)
326 depth = 3
327 type is (propagator_bomd_t)
328 depth = 1
329 class default
330 message(1) = "The chosen propagator does not yet support interaction interpolation"
331 call messages_fatal(1, namespace=this%namespace)
332 end select
333
334 call interaction%init_interpolation(depth, interaction%label)
335 end select
336
337 pop_sub(electrons_init_interactions)
338 end subroutine electrons_init_interaction
339
340 ! ---------------------------------------------------------
341 subroutine electrons_init_parallelization(this, grp)
342 class(electrons_t), intent(inout) :: this
343 type(mpi_grp_t), intent(in) :: grp
344
345 integer(int64) :: index_range(4)
346 real(real64) :: mesh_global, mesh_local, wfns
347 integer :: idir
348 real(real64) :: spiral_q(3), spiral_q_red(3)
349 type(block_t) :: blk
350
352
353 call mpi_grp_copy(this%grp, grp)
354
355 ! store the ranges for these two indices (serves as initial guess
356 ! for parallelization strategy)
357 index_range(1) = this%gr%np_global ! Number of points in mesh
358 index_range(2) = this%st%nst ! Number of states
359 index_range(3) = this%st%nik ! Number of k-points
360 index_range(4) = 100000 ! Some large number
361
362 ! create index and domain communicators
363 call multicomm_init(this%mc, this%namespace, this%grp, calc_mode_par, &
364 mpi_world%size, index_range, (/ 5000, 1, 1, 1 /))
365
366 call this%ions%partition(this%mc)
367 call kpoints_distribute(this%st, this%mc)
368 call states_elec_distribute_nodes(this%st, this%namespace, this%mc)
369
370
371 if (parse_is_defined(this%namespace, 'TDMomentumTransfer') .or. &
372 parse_is_defined(this%namespace, 'TDReducedMomentumTransfer')) then
373 if (parse_block(this%namespace, 'TDMomentumTransfer', blk) == 0) then
374 do idir = 1, this%space%dim
375 call parse_block_float(blk, 0, idir - 1, spiral_q(idir))
376 end do
377 else if(parse_block(this%namespace, 'TDReducedMomentumTransfer', blk) == 0) then
378 do idir = 1, this%space%dim
379 call parse_block_float(blk, 0, idir - 1, spiral_q_red(idir))
380 end do
381 call kpoints_to_absolute(this%kpoints%latt, spiral_q_red(1:this%space%dim), spiral_q(1:this%space%dim))
382 end if
383 call parse_block_end(blk)
384 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc, spiral_q)
385 else
386 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
387 end if
388
389 if (this%st%symmetrize_density) then
390 call mesh_check_symmetries(this%gr, this%gr%symm, this%ions%space%periodic_dim)
391 end if
392
393 call output_init(this%outp, this%namespace, this%space, this%st, this%gr, this%st%nst, this%ks)
394 call states_elec_densities_init(this%st, this%gr)
395 call states_elec_exec_init(this%st, this%namespace, this%mc)
396
397 if (associated(this%photons)) then
398 this%ks%has_photons = .true.
399 end if
400
401 call v_ks_init(this%ks, this%namespace, this%gr, this%st, this%ions, this%mc, this%space, this%kpoints)
402 if (this%ks%theory_level == kohn_sham_dft .or. this%ks%theory_level == generalized_kohn_sham_dft) then
403 this%xc_interaction => xc_interaction_t(this)
404 end if
405
406 ! For the moment the photons are initialized here
407
408 if(this%ks%has_photons) then
409 this%ks%pt => this%photons%modes
410 ! Temporary creation that should go in the system initialization later
411 call photon_mode_set_n_electrons(this%photons%modes, this%st%qtot)
412 write(message(1), '(a,i5,a)') 'Happy to have ', this%photons%modes%nmodes, ' photon modes with us.'
413 call messages_info(1)
414 call mf_init(this%ks%pt_mx, this%gr, this%st, this%ions, this%ks%pt)
415 ! OEP for photons
416 if(bitand(this%ks%xc_family, xc_family_oep) /= 0 .and. this%ks%xc%functional(func_x,1)%id == xc_oep_x) then
417 this%ks%oep_photon%level = this%ks%oep%level
418 call xc_oep_photon_init(this%ks%oep_photon, this%namespace, this%ks%xc_family, this%gr, this%st, this%mc, this%space)
419 else
420 this%ks%oep_photon%level = oep_level_none
421 end if
422
423 end if
424
425
426 ! Temporary place for the initialization of the lasers
427 this%lasers => lasers_t(this%namespace)
428 call lasers_parse_external_fields(this%lasers)
429 call lasers_generate_potentials(this%lasers, this%gr, this%space, this%ions%latt)
430 if(this%lasers%no_lasers > 0) then
431 call this%ext_partners%add(this%lasers)
432 call lasers_check_symmetries(this%lasers, this%kpoints)
433 else
434 deallocate(this%lasers)
435 end if
436
437 ! Temporary place for the initialization of the gauge field
438 this%gfield => gauge_field_t(this%namespace, this%ions%latt%rcell_volume)
439 if(gauge_field_is_used(this%gfield)) then
440 call this%ext_partners%add(this%gfield)
441 call gauge_field_check_symmetries(this%gfield, this%kpoints)
442 else
443 deallocate(this%gfield)
444 end if
445
446 call hamiltonian_elec_init(this%hm, this%namespace, this%space, this%gr, this%ions, this%ext_partners, &
447 this%st, this%ks%theory_level, this%ks%xc, this%mc, this%kpoints, &
448 need_exchange = output_need_exchange(this%outp) .or. this%ks%oep%level /= oep_level_none, &
449 xc_photons = this%ks%xc_photons )
450
451 if (this%hm%pcm%run_pcm .and. this%mc%par_strategy /= p_strategy_serial .and. this%mc%par_strategy /= p_strategy_states) then
452 call messages_experimental('Parallel in domain calculations with PCM')
453 end if
454
455 ! Print memory requirements
456 call messages_print_with_emphasis(msg='Approximate memory requirements', namespace=this%namespace)
457
458 mesh_global = mesh_global_memory(this%gr)
459 mesh_local = mesh_local_memory(this%gr)
460
461 call messages_write('Mesh')
462 call messages_new_line()
463 call messages_write(' global :')
464 call messages_write(mesh_global, units = unit_megabytes, fmt = '(f10.1)')
465 call messages_new_line()
466 call messages_write(' local :')
467 call messages_write(mesh_local, units = unit_megabytes, fmt = '(f10.1)')
468 call messages_new_line()
469 call messages_write(' total :')
470 call messages_write(mesh_global + mesh_local, units = unit_megabytes, fmt = '(f10.1)')
471 call messages_new_line()
472 call messages_info(namespace=this%namespace)
473
474 wfns = states_elec_wfns_memory(this%st, this%gr)
475 call messages_write('States')
476 call messages_new_line()
477 call messages_write(' real :')
478 call messages_write(wfns, units = unit_megabytes, fmt = '(f10.1)')
479 call messages_write(' (par_kpoints + par_states + par_domains)')
480 call messages_new_line()
481 call messages_write(' complex :')
482 call messages_write(2.0_8*wfns, units = unit_megabytes, fmt = '(f10.1)')
483 call messages_write(' (par_kpoints + par_states + par_domains)')
484 call messages_new_line()
485 call messages_info(namespace=this%namespace)
486
487 call messages_print_with_emphasis(namespace=this%namespace)
488
489 if (this%generate_epot) then
490 message(1) = "Info: Generating external potential"
491 call messages_info(1, namespace=this%namespace)
492 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
493 this%ext_partners, this%st)
494 message(1) = " done."
495 call messages_info(1, namespace=this%namespace)
496 end if
497
498 if (this%ks%theory_level /= independent_particles) then
499 call poisson_async_init(this%hm%psolver, this%mc)
500 ! slave nodes do not call the calculation routine
501 if (multicomm_is_slave(this%mc)) then
502 !for the moment we only have one type of slave
503 call poisson_slave_work(this%hm%psolver, this%namespace)
504 end if
505 end if
506
507 allocate(this%supported_interactions(0))
508 select case (this%hm%mxll%coupling_mode)
510 this%supported_interactions = [this%supported_interactions, mxll_e_field_to_matter]
512 this%supported_interactions = [this%supported_interactions, mxll_vec_pot_to_matter]
513 if (this%hm%mxll%add_zeeman) then
514 this%supported_interactions = [this%supported_interactions, mxll_b_field_to_matter]
515 end if
517 if (this%hm%mxll%add_electric_dip .or. this%hm%mxll%add_electric_quad) then
518 this%supported_interactions = [this%supported_interactions, mxll_e_field_to_matter]
519 end if
520 if (this%hm%mxll%add_magnetic_dip) then
521 this%supported_interactions = [this%supported_interactions, mxll_b_field_to_matter]
522 end if
524 ! Do not initialize any interaction with Maxwell
525 case default
526 message(1) = "Unknown maxwell-matter coupling"
527 call messages_fatal(1, namespace=this%namespace)
528 end select
529
531 end subroutine electrons_init_parallelization
532
533 ! ---------------------------------------------------------
534 subroutine electrons_new_algorithm(this, factory)
535 class(electrons_t), intent(inout) :: this
536 class(algorithm_factory_t), intent(in) :: factory
537
539
540 call system_new_algorithm(this, factory)
541
542 select type (algo => this%algo)
543 class is (propagator_t)
544
545 call td_init(this%td, this%namespace, this%space, this%gr, this%ions, this%st, this%ks, &
546 this%hm, this%ext_partners, this%outp)
547
548 ! this corresponds to the first part of td_init_run
549 call td_allocate_wavefunctions(this%td, this%namespace, this%mc, this%gr, this%ions, this%st, &
550 this%hm, this%space)
551 call td_init_gaugefield(this%td, this%namespace, this%gr, this%st, this%ks, this%hm, &
552 this%ext_partners, this%space)
553
554 class is (minimizer_algorithm_t)
555
556 call gs_allocate_wavefunctions(this%namespace, this%gr, this%st, this%hm, this%scf, this%ks, &
557 this%ions, this%mc, this%space)
558
559 class default
560 assert(.false.)
561 end select
562
564 end subroutine electrons_new_algorithm
565
566 ! ---------------------------------------------------------
567 subroutine electrons_initialize(this)
568 class(electrons_t), intent(inout) :: this
569
570 push_sub(electrons_initialize)
571
572 select type (algo => this%algo)
573 class is (propagator_t)
574 call td_set_from_scratch(this%td, .true.)
575 call td_load_restart_from_gs(this%td, this%namespace, this%space, this%mc, this%gr, &
576 this%ext_partners, this%st, this%ks, this%hm)
577
578 class is (minimizer_algorithm_t)
579
580 call gs_initialize(this%namespace, this%scf, this%rdm, this%gr, this%mc, this%st, &
581 this%hm, this%ions, this%ks, this%space, this%ext_partners, fromscratch=.true.)
582 class default
583 assert(.false.)
584 end select
585
586 pop_sub(electrons_initialize)
587 end subroutine electrons_initialize
588
589 ! ---------------------------------------------------------
590 subroutine electrons_algorithm_start(this)
591 class(electrons_t), intent(inout) :: this
592
594
595 call system_algorithm_start(this)
596
597 select type (algo => this%algo)
598 class is (propagator_t)
599
600 ! additional initialization needed for electrons
601 call td_init_with_wavefunctions(this%td, this%namespace, this%space, this%mc, this%gr, this%ions, &
602 this%ext_partners, this%st, this%ks, this%hm, this%outp, td_get_from_scratch(this%td))
603
604 end select
605
607 end subroutine electrons_algorithm_start
608
609 ! ---------------------------------------------------------
610 logical function electrons_do_algorithmic_operation(this, operation, updated_quantities) result(done)
611 class(electrons_t), intent(inout) :: this
612 class(algorithmic_operation_t), intent(in) :: operation
613 integer, allocatable, intent(out) :: updated_quantities(:)
614
615 logical :: update_energy_
616 type(gauge_field_t), pointer :: gfield
617 real(real64) :: time
618 integer :: iter
619
621 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
622
623 update_energy_ = .true.
624
625 ! kick at t > 0 still missing!
626
627 done = .true.
628 select type (algo => this%algo)
629 class is (propagator_t)
630 time = algo%iteration%value()
631 select case (operation%id)
632 case (aetrs_first_half)
633 ! propagate half of the time step with H(time)
634 call get_fields_from_interaction(this, time)
635 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
636 this%hm, this%ext_partners, time)
637 call propagation_ops_elec_exp_apply(this%td%tr%te, this%namespace, this%st, this%gr, this%hm, m_half*algo%dt)
638
639 case (aetrs_extrapolate)
640 ! Do the extrapolation of the Hamiltonian
641 ! First the extrapolation of the potential
642 call potential_interpolation_new(this%td%tr%vksold, this%gr%np, this%st%d%nspin, &
643 time+algo%dt, algo%dt, this%hm%vhxc, vtau=this%hm%vtau)
644
645 !Get the potentials from the interpolator
646 call propagation_ops_elec_interpolate_get(this%gr, this%hm, this%td%tr%vksold)
647
648 ! Second the ions and gauge field which later on will be treated as extrapolation
649 ! of interactions, but this is not yet possible
650
651 ! move the ions to time t
652 call propagation_ops_elec_move_ions(this%td%tr%propagation_ops_elec, this%gr, this%hm, &
653 this%st, this%namespace, this%space, this%td%ions_dyn, this%ions, this%ext_partners, &
654 time+algo%dt, algo%dt)
655
656 !Propagate gauge field
657 gfield => list_get_gauge_field(this%ext_partners)
658 if(associated(gfield)) then
659 call propagation_ops_elec_propagate_gauge_field(this%td%tr%propagation_ops_elec, gfield, &
660 algo%dt, time+algo%dt)
661 end if
662
663 !Update Hamiltonian and current
664 call get_fields_from_interaction(this, time+algo%dt)
665 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
666 this%hm, this%ext_partners, time+algo%dt)
667
668 case (aetrs_second_half)
669 !Do the time propagation for the second half of the time step
670 call propagation_ops_elec_fuse_density_exp_apply(this%td%tr%te, this%namespace, this%st, &
671 this%gr, this%hm, m_half*algo%dt)
672
673 case (expmid_extrapolate)
674 ! the half step of this propagator screws with the gauge field kick
675 gfield => list_get_gauge_field(this%ext_partners)
676 if(associated(gfield)) then
677 assert(gauge_field_is_propagated(gfield) .eqv. .false.)
678 end if
679
680 ! Do the extrapolation of the Hamiltonian
681 ! First the extrapolation of the potential
682 call potential_interpolation_new(this%td%tr%vksold, this%gr%np, this%st%d%nspin, &
683 time+algo%dt, algo%dt, this%hm%vhxc, vtau=this%hm%vtau)
684
685 ! get the potentials from the interpolator
686 if (this%hm%theory_level /= independent_particles) then
687 call potential_interpolation_interpolate(this%td%tr%vksold, 3, &
688 time+algo%dt, algo%dt, time + algo%dt/m_two, &
689 this%hm%vhxc, vtau=this%hm%vtau)
690 end if
691
692 ! Second the ions which later on will be treated as extrapolation of interactions,
693 ! but this is not yet possible
694 ! move the ions to the half step
695 call propagation_ops_elec_move_ions(this%td%tr%propagation_ops_elec, this%gr, this%hm, this%st, &
696 this%namespace, this%space, this%td%ions_dyn, this%ions, this%ext_partners, &
697 time + m_half*algo%dt, m_half*algo%dt, save_pos=.true.)
698
699 call get_fields_from_interaction(this, time + m_half*algo%dt)
700 call propagation_ops_elec_update_hamiltonian(this%namespace, this%space, this%st, this%gr, &
701 this%hm, this%ext_partners, time + m_half*algo%dt)
702
704 ! Do the actual propagation step
705 call propagation_ops_elec_fuse_density_exp_apply(this%td%tr%te, this%namespace, this%st, &
706 this%gr, this%hm, algo%dt)
707
708 ! restore to previous time
709 call propagation_ops_elec_restore_ions(this%td%tr%propagation_ops_elec, this%td%ions_dyn, this%ions)
710
711 case (bomd_start)
712 call scf_init(this%scf, this%namespace, this%gr, this%ions, this%st, this%mc, this%hm, this%space)
713 ! the ions are propagated inside the propagation step already, so no need to do it at the end
714 this%ions_propagated = .true.
715
716 case (verlet_update_pos)
717 ! move the ions to time t
718 call ion_dynamics_propagate(this%td%ions_dyn, this%ions, time+algo%dt, &
719 algo%dt, this%namespace)
720
721 case (bomd_elec_scf)
722 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
723 this%ext_partners, this%st, time = time+algo%dt)
724 ! now calculate the eigenfunctions
725 call scf_run(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
726 this%ext_partners, this%st, this%ks, this%hm, verbosity = verb_compact)
727 ! TODO: Check if this call is realy needed. - NTD
728 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
729 this%ext_partners, this%st, time = time+algo%dt)
730
731 ! update Hamiltonian and eigenvalues (fermi is *not* called)
732 call v_ks_calc(this%ks, this%namespace, this%space, this%hm, this%st, this%ions, this%ext_partners, &
733 calc_eigenval = .true., time = time+algo%dt, calc_energy = .true.)
734
735 ! Get the energies.
736 call energy_calc_total(this%namespace, this%space, this%hm, this%gr, this%st, this%ext_partners, iunit = -1)
737
738 case (verlet_compute_acc)
739 ! Do nothing, forces are computing in scf_run
740
741 case (verlet_compute_vel)
742 call ion_dynamics_propagate_vel(this%td%ions_dyn, this%ions)
743 ! TODO: Check if this call is realy needed. - NTD
744 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
745 this%ext_partners, this%st, time = time+algo%dt)
746 call this%ions%update_kinetic_energy()
747
748 case (expmid_start)
749 this%ions_propagated = .false.
750
751 case (aetrs_start)
752 ! the ions are propagated inside the propagation step already, so no need to do it at the end
753 this%ions_propagated = .true.
754
755 case (iteration_done)
757 done = .false.
758
759 case (bomd_finish)
760 call scf_end(this%scf)
761
763 case default
764 done = .false.
765 end select
766
767 class is(minimizer_algorithm_t)
768
769 ! Clocks starts at 0....
770 iter = nint(this%iteration%value()) + 1
771
772 select case(operation%id)
773 case (gs_scf_start)
774 call scf_start(this%scf, this%namespace, this%space, this%gr, this%ions, this%st, this%ks, &
775 this%hm, this%outp)
776
777 case (gs_scf_iteration)
778
779 call scf_iter(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
780 this%ext_partners, this%st, this%ks, this%hm, iter, outp = this%outp, &
781 restart_dump=this%scf%restart_dump)
782
783 algo%converged = scf_iter_finish(this%scf, this%namespace, this%space, this%gr, this%ions,&
784 this%st, this%ks, this%hm, iter, outp = this%outp)
785
786 case (gs_scf_finish)
787
788 ! Here iteration is iter-1, as the clock ticked before SCF_FINISH
789 call scf_finish(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
790 this%ext_partners, this%st, this%ks, this%hm, iter-1, &
791 outp = this%outp, restart_dump=this%scf%restart_dump)
792
793 case default
794 done = .false.
795 end select
796 class default
797 done = .false.
798 end select
799
800 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
803
804 ! ---------------------------------------------------------
805 logical function electrons_is_tolerance_reached(this, tol) result(converged)
806 class(electrons_t), intent(in) :: this
807 real(real64), intent(in) :: tol
808
810
811 converged = .false.
812
815
816 ! ---------------------------------------------------------
817 subroutine electrons_update_quantity(this, iq)
818 class(electrons_t), intent(inout) :: this
819 integer, intent(in) :: iq
820
822 call profiling_in(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
823
824 ! We are only allowed to update quantities that can be updated on demand
825 assert(this%quantities(iq)%updated_on_demand)
826
827 select case (iq)
828 case (current)
829 call states_elec_allocate_current(this%st, this%space, this%gr)
830 call current_calculate(this%current_calculator, this%namespace, this%gr, &
831 this%hm, this%space, this%st)
832 case (dipole)
833 call this%dipole%calculate(this%gr, this%ions, this%st)
834 case default
835 message(1) = "Incompatible quantity."
836 call messages_fatal(1, namespace=this%namespace)
837 end select
838
839 call profiling_out(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
841 end subroutine electrons_update_quantity
842
843 ! ---------------------------------------------------------
844 subroutine electrons_init_interaction_as_partner(partner, interaction)
845 class(electrons_t), intent(in) :: partner
846 class(interaction_surrogate_t), intent(inout) :: interaction
847
849
850 select type (interaction)
852 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
853 class default
854 message(1) = "Unsupported interaction."
855 call messages_fatal(1, namespace=partner%namespace)
856 end select
857
860
861 ! ---------------------------------------------------------
862 subroutine electrons_copy_quantities_to_interaction(partner, interaction)
863 class(electrons_t), intent(inout) :: partner
864 class(interaction_surrogate_t), intent(inout) :: interaction
865
867 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
868
869 select type (interaction)
871 assert(allocated(partner%st%current))
872 interaction%partner_field(:,:) = partner%st%current(1:partner%gr%np,:,1)
873 call interaction%do_mapping()
874 class default
875 message(1) = "Unsupported interaction."
876 call messages_fatal(1, namespace=partner%namespace)
877 end select
878
879 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
882
883 ! ---------------------------------------------------------
884 subroutine electrons_output_start(this)
885 class(electrons_t), intent(inout) :: this
886
887 push_sub(electrons_output_start)
888
890 end subroutine electrons_output_start
891
892 ! ---------------------------------------------------------
893 subroutine electrons_output_write(this)
894 class(electrons_t), intent(inout) :: this
895
896 integer :: iter
897
899 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
900
901 select type (algo => this%algo)
902 class is (propagator_t)
903 iter = this%iteration%counter()
904
905 call td_write_iter(this%td%write_handler, this%namespace, this%space, this%outp, this%gr, &
906 this%st, this%hm, this%ions, this%ext_partners, this%hm%kick, this%ks, algo%dt, iter, this%mc, this%td%recalculate_gs)
907
908 if (this%outp%anything_now(iter)) then ! output
909 call td_write_output(this%namespace, this%space, this%gr, this%st, this%hm, this%ks, &
910 this%outp, this%ions, this%ext_partners, iter, algo%dt)
911 end if
912 end select
913
914 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
916 end subroutine electrons_output_write
917
918 ! ---------------------------------------------------------
919 subroutine electrons_output_finish(this)
920 class(electrons_t), intent(inout) :: this
921
923
925 end subroutine electrons_output_finish
926
927 ! ---------------------------------------------------------
928 logical function electrons_process_is_slave(this) result(is_slave)
929 class(electrons_t), intent(in) :: this
930
932
933 is_slave = multicomm_is_slave(this%mc)
934
936 end function electrons_process_is_slave
938 ! ---------------------------------------------------------
939 subroutine electrons_exec_end_of_timestep_tasks(this, prop)
940 class(electrons_t), intent(inout) :: this
941 class(propagator_t), intent(in) :: prop
942
943 logical :: stopping
944 logical :: generate
945 logical :: update_energy_
946 integer :: nt
947 real(real64) :: time
948 type(gauge_field_t), pointer :: gfield
949
951 call profiling_in(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
952
953 stopping = .false.
954
955 nt = this%td%iter
956 ! this is the time at the end of the timestep, as required in all routines here
957 time = prop%dt*nt
958 update_energy_ = .true.
959
960 !Apply mask absorbing boundaries
961 if (this%hm%abs_boundaries%abtype == mask_absorbing) call zvmask(this%gr, this%hm, this%st)
962
963 !Photoelectron stuff
964 if (this%td%pesv%calc_spm .or. this%td%pesv%calc_mask .or. this%td%pesv%calc_flux) then
965 call pes_calc(this%td%pesv, this%namespace, this%space, this%gr, this%st, &
966 prop%dt, nt, this%gr%der, this%hm%kpoints, this%ext_partners, stopping)
967 end if
968
969 ! For BOMD, we do not want the lines below to be executed
970 select type(prop)
971 type is(propagator_bomd_t)
972 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
974 return
975 end select
976
977 ! The propagation of the ions and the gauge field is currently done here.
978 ! TODO: this code is to be moved to their own systems at some point
979 generate = .false.
980 if (ion_dynamics_ions_move(this%td%ions_dyn)) then
981 if (.not. this%ions_propagated) then
982 call ion_dynamics_propagate(this%td%ions_dyn, this%ions, abs(nt*prop%dt), this%td%ions_dyn%ionic_scale*prop%dt, &
983 this%namespace)
984 generate = .true.
985 end if
986 end if
987
988 gfield => list_get_gauge_field(this%ext_partners)
989 if(associated(gfield)) then
990 if (gauge_field_is_propagated(gfield) .and. .not. this%ions_propagated) then
992 end if
993 end if
994
995 if (generate .or. this%ions%has_time_dependent_species()) then
996 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
997 this%ext_partners, this%st, time = abs(nt*prop%dt))
998 end if
999
1000 call v_ks_calc(this%ks, this%namespace, this%space, this%hm, this%st, this%ions, this%ext_partners, &
1001 calc_eigenval = update_energy_, time = abs(nt*prop%dt), calc_energy = update_energy_)
1002
1003 if (update_energy_) then
1004 call energy_calc_total(this%namespace, this%space, this%hm, this%gr, this%st, this%ext_partners, iunit = -1)
1005 end if
1006
1007 ! Recalculate forces, update velocities...
1008 if (ion_dynamics_ions_move(this%td%ions_dyn)) then
1009 call forces_calculate(this%gr, this%namespace, this%ions, this%hm, this%ext_partners, this%st, &
1010 this%ks, t = abs(nt*prop%dt), dt = prop%dt)
1011 call ion_dynamics_propagate_vel(this%td%ions_dyn, this%ions, atoms_moved = generate)
1012 call this%ions%update_kinetic_energy()
1013 else
1014 if (this%outp%what(option__output__forces) .or. this%td%write_handler%out(out_separate_forces)%write) then
1015 call forces_calculate(this%gr, this%namespace, this%ions, this%hm, this%ext_partners, &
1016 this%st, this%ks, t = abs(nt*prop%dt), dt = prop%dt)
1017 end if
1018 end if
1019
1020 if (this%outp%what(option__output__stress)) then
1021 call stress_calculate(this%namespace, this%gr, this%hm, this%st, this%ions, this%ks, this%ext_partners)
1022 end if
1023
1024 if(associated(gfield)) then
1025 if(gauge_field_is_propagated(gfield)) then
1026 if(this%ks%xc%kernel_lrc_alpha>m_epsilon) then
1027 call gauge_field_get_force(gfield, this%gr, this%st%d%spin_channels, this%st%current, this%ks%xc%kernel_lrc_alpha)
1028 else
1029 call gauge_field_get_force(gfield, this%gr, this%st%d%spin_channels, this%st%current)
1030 endif
1032 end if
1033 end if
1034
1035 !We update the occupation matrices
1036 call lda_u_update_occ_matrices(this%hm%lda_u, this%namespace, this%gr, this%st, this%hm%hm_base, this%hm%phase, this%hm%energy)
1037
1038 ! this is needed to be compatible with the code in td_*
1039 this%td%iter = this%td%iter + 1
1040
1041 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
1044
1045 ! ---------------------------------------------------------
1046 subroutine electrons_restart_write_data(this)
1047 class(electrons_t), intent(inout) :: this
1048
1049 integer :: ierr
1050
1052 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
1053
1054 select type (algo => this%algo)
1055 class is (propagator_t)
1056 call td_write_data(this%td%write_handler)
1057 call td_dump(this%td, this%namespace, this%space, this%gr, this%st, this%hm, &
1058 this%ks, this%ext_partners, this%iteration%counter(), ierr)
1059 if (ierr /= 0) then
1060 message(1) = "Unable to write time-dependent restart information."
1061 call messages_warning(1, namespace=this%namespace)
1062 end if
1063
1064 ! TODO: this is here because of legacy reasons and should be moved to the output framework
1065 call pes_output(this%td%pesv, this%namespace, this%space, this%gr, this%st, this%iteration%counter(), &
1066 this%outp, algo%dt, this%ions)
1067 end select
1068
1069 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
1071 end subroutine electrons_restart_write_data
1072
1073 ! ---------------------------------------------------------
1074 ! this function returns true if restart data could be read
1075 logical function electrons_restart_read_data(this)
1076 class(electrons_t), intent(inout) :: this
1077
1078 logical :: from_scratch
1079
1081 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
1082
1083 select type (algo => this%algo)
1084 class is (propagator_t)
1085 from_scratch = .false.
1086 call td_load_restart_from_td(this%td, this%namespace, this%space, this%mc, this%gr, &
1087 this%ext_partners, this%st, this%ks, this%hm, from_scratch)
1088 call td_set_from_scratch(this%td, from_scratch)
1089
1090 class is (minimizer_algorithm_t)
1091 from_scratch = .false.
1092 call gs_load_from_restart(this%namespace, this%scf, this%gr, this%mc, this%st, this%hm, &
1093 this%ks, this%space, this%ions, this%ext_partners,from_scratch)
1094
1095 ! gs_initialize still knows about fromScratch.
1096 assert(.false.)
1097 end select
1098
1099 if (from_scratch) then
1100 ! restart data could not be loaded
1102 else
1103 ! restart data could be loaded
1105 end if
1106
1107 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
1109 end function electrons_restart_read_data
1110
1111 !----------------------------------------------------------
1112 subroutine electrons_update_kinetic_energy(this)
1113 class(electrons_t), intent(inout) :: this
1114
1116
1117 if (states_are_real(this%st)) then
1118 this%kinetic_energy = denergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1119 else
1120 this%kinetic_energy = zenergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1121 end if
1122
1124
1125 end subroutine electrons_update_kinetic_energy
1126
1127 ! ---------------------------------------------------------
1128 subroutine get_fields_from_interaction(this, time)
1129 class(electrons_t), intent(inout) :: this
1130 real(real64), intent(in) :: time
1131
1132 type(interaction_iterator_t) :: iter
1133 real(real64), allocatable :: field_tmp(:, :)
1134
1136
1137 if (this%hm%mxll%coupling_mode == no_maxwell_coupling) then
1139 return
1140 end if
1141
1142 safe_allocate(field_tmp(1:this%gr%np, 1:this%gr%box%dim))
1143 this%hm%mxll%e_field = m_zero
1144 this%hm%mxll%b_field = m_zero
1145 this%hm%mxll%vec_pot = m_zero
1146
1147 ! interpolate field from interaction
1148 call iter%start(this%interactions)
1149 do while (iter%has_next())
1150 select type (interaction => iter%get_next())
1151 class is (mxll_e_field_to_matter_t)
1152 call interaction%interpolate(time, field_tmp)
1153 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%e_field)
1154 class is (mxll_vec_pot_to_matter_t)
1155 call interaction%interpolate(time, field_tmp)
1156 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%vec_pot)
1157 class is (mxll_b_field_to_matter_t)
1158 call interaction%interpolate(time, field_tmp)
1159 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%b_field)
1160 end select
1161 end do
1162
1163 safe_deallocate_a(field_tmp)
1165
1166 end subroutine get_fields_from_interaction
1167
1168 !----------------------------------------------------------
1169 subroutine electrons_finalize(sys)
1170 type(electrons_t), intent(inout) :: sys
1171
1172 type(partner_iterator_t) :: iter
1173 class(interaction_partner_t), pointer :: partner
1174
1175 push_sub(electrons_finalize)
1176
1177 if (associated(sys%algo)) then
1178 select type (algo => sys%algo)
1179 class is (propagator_t)
1180 call td_end_run(sys%td, sys%st, sys%hm)
1181 call td_end(sys%td)
1182 class is(minimizer_algorithm_t)
1183 call gs_cleanup(sys%ks, sys%scf, sys%rdm, sys%st, sys%hm)
1184 end select
1185 end if
1186
1187 if (sys%ks%theory_level /= independent_particles) then
1188 call poisson_async_end(sys%hm%psolver, sys%mc)
1189 end if
1190
1191 call iter%start(sys%ext_partners)
1192 do while (iter%has_next())
1193 partner => iter%get_next()
1194 safe_deallocate_p(partner)
1195 end do
1196 call sys%ext_partners%empty()
1197
1198 safe_deallocate_p(sys%xc_interaction)
1199
1200 call hamiltonian_elec_end(sys%hm)
1201
1202 nullify(sys%gfield)
1203 nullify(sys%lasers)
1204
1205 call multicomm_end(sys%mc)
1206
1207 call xc_oep_photon_end(sys%ks%oep_photon)
1208 if (sys%ks%has_photons) then
1209 call mf_end(sys%ks%pt_mx)
1210 end if
1211
1212 call sys%dipole%end()
1213
1214 call v_ks_end(sys%ks)
1215
1216 call states_elec_end(sys%st)
1217
1218 deallocate(sys%ions)
1219 safe_deallocate_p(sys%photons)
1220
1221 call kpoints_end(sys%kpoints)
1222
1223 call grid_end(sys%gr)
1224
1225 call system_end(sys)
1226
1227 pop_sub(electrons_finalize)
1228 end subroutine electrons_finalize
1229
1230end module electrons_oct_m
1231
1232!! Local Variables:
1233!! mode: f90
1234!! coding: utf-8
1235!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:170
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:141
character(len=algo_label_len), parameter, public iteration_done
Definition: algorithm.F90:172
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:367
subroutine, public current_init(this, namespace)
Definition: current.F90:177
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
This modules implements the dipole moment of the matter system.
Definition: dipole.F90:108
subroutine, public gs_cleanup(ks, scf, rdm, st, hm)
subroutine, public gs_initialize(namespace, scf, rdm, gr, mc, st, hm, ions, ks, space, ext_partners, fromScratch)
subroutine, public gs_allocate_wavefunctions(namespace, gr, st, hm, scf, ks, ions, mc, space)
subroutine, public gs_load_from_restart(namespace, scf, gr, mc, st, hm, ks, space, ions, ext_partners, fromScratch)
subroutine electrons_initialize(this)
Definition: electrons.F90:661
logical function electrons_restart_read_data(this)
Definition: electrons.F90:1169
subroutine electrons_init_parallelization(this, grp)
Definition: electrons.F90:435
logical function electrons_process_is_slave(this)
Definition: electrons.F90:1022
subroutine electrons_init_interaction(this, interaction)
Definition: electrons.F90:372
subroutine electrons_finalize(sys)
Definition: electrons.F90:1263
subroutine electrons_exec_end_of_timestep_tasks(this, prop)
Definition: electrons.F90:1033
logical function electrons_do_algorithmic_operation(this, operation, updated_quantities)
Definition: electrons.F90:704
subroutine electrons_new_algorithm(this, factory)
Definition: electrons.F90:628
subroutine electrons_update_quantity(this, iq)
Definition: electrons.F90:911
subroutine electrons_output_write(this)
Definition: electrons.F90:987
subroutine get_fields_from_interaction(this, time)
Definition: electrons.F90:1222
subroutine electrons_algorithm_start(this)
Definition: electrons.F90:684
subroutine electrons_output_finish(this)
Definition: electrons.F90:1013
subroutine electrons_output_start(this)
Definition: electrons.F90:978
subroutine electrons_init_interaction_as_partner(partner, interaction)
Definition: electrons.F90:938
class(electrons_t) function, pointer electrons_constructor(namespace, generate_epot)
Definition: electrons.F90:282
subroutine electrons_update_kinetic_energy(this)
Definition: electrons.F90:1206
logical function electrons_is_tolerance_reached(this, tol)
Definition: electrons.F90:899
subroutine electrons_copy_quantities_to_interaction(partner, interaction)
Definition: electrons.F90:956
subroutine electrons_restart_write_data(this)
Definition: electrons.F90:1140
subroutine, public elf_init(namespace)
Definition: elf.F90:144
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:336
subroutine, public gauge_field_do_algorithmic_operation(this, operation, dt, time)
subroutine, public gauge_field_check_symmetries(this, kpoints)
subroutine, public gauge_field_get_force(this, gr, spin_channels, current, lrc_alpha)
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:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_epsilon
Definition: global.F90:203
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public m_one
Definition: global.F90:188
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public grid_init_stage_1(gr, namespace, space, symm, latt, n_sites, site_position)
First stage of the grid initialization.
Definition: grid.F90:194
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
Definition: grid.F90:465
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:493
integer, parameter, public term_kinetic
integer, parameter, public generalized_kohn_sham_dft
subroutine, public zvmask(mesh, hm, st)
subroutine, public hamiltonian_elec_end(hm)
integer, parameter, public independent_particles
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 kohn_sham_dft
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(this, ions, time, dt, namespace)
logical pure function, public ion_dynamics_ions_move(this)
subroutine, public ion_dynamics_propagate_vel(this, ions, atoms_moved)
subroutine, public kpoints_end(this)
Definition: kpoints.F90:1012
subroutine, public kpoints_init(this, namespace, symm, dim, periodic_dim, latt)
Definition: kpoints.F90:322
subroutine, public kpoints_to_absolute(latt, kin, kout)
Definition: kpoints.F90:1031
subroutine, public lasers_check_symmetries(this, kpoints)
Definition: lasers.F90:553
subroutine, public lasers_parse_external_fields(this)
Definition: lasers.F90:243
subroutine, public lasers_generate_potentials(this, mesh, space, latt)
Definition: lasers.F90:442
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, hm_base, phase, energy)
Definition: lda_u.F90:796
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public mesh_check_symmetries(mesh, symm, periodic_dim)
Definition: mesh.F90:832
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:380
real(real64) pure function, public mesh_global_memory(mesh)
Definition: mesh.F90:779
real(real64) pure function, public mesh_local_memory(mesh)
Definition: mesh.F90:790
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:930
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1057
subroutine, public messages_new_line()
Definition: messages.F90:1146
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1097
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:624
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
subroutine mpi_grp_copy(mpi_grp_out, mpi_grp_in)
Definition: mpi.F90:403
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
subroutine, public multicomm_end(mc)
Definition: multicomm.F90:889
logical pure function, public multicomm_is_slave(this)
Definition: multicomm.F90:1133
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:264
integer, parameter, public mxll_field_trans
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
this module contains the output system
Definition: output_low.F90:115
this module contains the output system
Definition: output.F90:115
logical function, public output_need_exchange(outp)
Definition: output.F90:877
subroutine, public output_init(outp, namespace, space, st, gr, nst, ks)
Definition: output.F90:206
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:502
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
subroutine, public pes_calc(pes, namespace, space, mesh, st, dt, iter, der, kpoints, ext_partners, stopping)
Definition: pes.F90:269
subroutine, public pes_output(pes, namespace, space, gr, st, iter, outp, dt, ions)
Definition: pes.F90:295
subroutine, public mf_init(this, gr, st, ions, pt_mode)
subroutine, public mf_end(this)
subroutine, public photon_mode_set_n_electrons(this, qtot)
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1339
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1391
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1364
subroutine, public potential_interpolation_interpolate(potential_interpolation, order, time, dt, t, vhxc, vtau)
subroutine, public potential_interpolation_new(potential_interpolation, np, nspin, time, dt, vhxc, vtau)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
subroutine, public propagation_ops_elec_restore_ions(wo, ions_dyn, ions)
subroutine, public propagation_ops_elec_move_ions(wo, gr, hm, st, namespace, space, ions_dyn, ions, ext_partners, time, dt, save_pos)
subroutine, public propagation_ops_elec_propagate_gauge_field(wo, gfield, dt, time, save_gf)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
subroutine, public propagation_ops_elec_exp_apply(te, namespace, st, mesh, hm, dt)
subroutine, public propagation_ops_elec_interpolate_get(mesh, hm, interp)
subroutine, public propagation_ops_elec_fuse_density_exp_apply(te, namespace, st, gr, hm, dt, dt2, vmagnus)
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:117
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:137
integer, parameter, public current
Definition: quantity.F90:146
integer, parameter, public dipole
Definition: quantity.F90:146
Implementation details for regridding.
Definition: regridding.F90:170
logical function, public scf_iter_finish(scf, namespace, space, gr, ions, st, ks, hm, iter, outp, verbosity, iters_done)
Definition: scf.F90:1211
subroutine, public scf_finish(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, iter, outp, verbosity, iters_done, restart_dump)
Definition: scf.F90:1291
integer, parameter, public verb_compact
Definition: scf.F90:202
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:253
subroutine, public scf_end(scf)
Definition: scf.F90:542
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:818
subroutine, public scf_iter(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, iter, outp, verbosity, iters_done, restart_dump)
Definition: scf.F90:862
subroutine, public scf_start(scf, namespace, space, gr, ions, st, ks, hm, outp, verbosity)
Preparation of the SCF cycle.
Definition: scf.F90:671
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:117
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)
@Brief. 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 states_elec_init(st, namespace, space, valence_charge, kpoints)
Initialize a new 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_allocate_current(st, space, mesh)
This module implements the calculation of the stress tensor.
Definition: stress.F90:118
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
Definition: stress.F90:184
This module implements the abstract system type.
Definition: system.F90:118
subroutine, public system_algorithm_start(this)
Definition: system.F90:999
subroutine, public system_end(this)
Definition: system.F90:1124
subroutine, public system_new_algorithm(this, factory)
Definition: system.F90:928
Definition: td.F90:114
subroutine, public td_end(td)
Definition: td.F90:610
subroutine, public td_load_restart_from_gs(td, namespace, space, mc, gr, ext_partners, st, ks, hm)
Definition: td.F90:1154
subroutine, public td_end_run(td, st, hm)
Definition: td.F90:625
subroutine, public td_init(td, namespace, space, gr, ions, st, ks, hm, ext_partners, outp)
Definition: td.F90:247
subroutine, public td_allocate_wavefunctions(td, namespace, mc, gr, ions, st, hm, space)
Definition: td.F90:545
logical function, public td_get_from_scratch(td)
Definition: td.F90:1498
subroutine, public td_set_from_scratch(td, from_scratch)
Definition: td.F90:1509
subroutine, public td_dump(td, namespace, space, gr, st, hm, ks, ext_partners, iter, ierr)
Definition: td.F90:1286
subroutine, public td_init_gaugefield(td, namespace, gr, st, ks, hm, ext_partners, space)
Definition: td.F90:579
subroutine, public td_init_with_wavefunctions(td, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, from_scratch)
Definition: td.F90:842
subroutine, public td_load_restart_from_td(td, namespace, space, mc, gr, ext_partners, st, ks, hm, from_scratch)
Definition: td.F90:1118
subroutine, public td_write_output(namespace, space, gr, st, hm, ks, outp, ions, ext_partners, iter, dt)
Definition: td_write.F90:1228
subroutine, public td_write_data(writ)
Definition: td_write.F90:1194
subroutine, public td_write_iter(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, kick, ks, dt, iter, mc, recalculate_gs)
Definition: td_write.F90:1029
integer, parameter, public out_separate_forces
Definition: td_write.F90:201
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:612
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:732
subroutine, public v_ks_init(ks, namespace, gr, st, ions, mc, space, kpoints)
Definition: v_ks.F90:243
integer, parameter, public xc_oep_x
Exact exchange.
integer, parameter, public func_x
Definition: xc.F90:114
integer, parameter, public oep_level_none
the OEP levels
Definition: xc_oep.F90:172
subroutine, public xc_oep_photon_init(oep, namespace, family, gr, st, mc, space)
subroutine, public xc_oep_photon_end(oep)
Abstract class for the algorithm factories.
Descriptor of one algorithmic operation.
Definition: algorithm.F90:163
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:218
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:142
class to transfer a Maxwell B field to a matter system
class to transfer a Maxwell 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:138
Abstract class for systems.
Definition: system.F90:172
int true(void)