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