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)
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%gr, this%ions, this%st, this%ks, this%hm, this%outp)
786
787 case (gs_scf_iteration)
788
789 call scf_iter(this%scf, this%namespace, this%space, this%mc, this%gr, this%ions, &
790 this%ext_partners, this%st, this%ks, this%hm, iter, outp = this%outp, &
791 restart_dump=this%scf%restart_dump)
792
793 algo%converged = scf_iter_finish(this%scf, this%namespace, this%space, this%gr, this%ions,&
794 this%st, this%ks, this%hm, iter, outp = this%outp)
795
796 updated_quantities = ["wavefunctions"]
797
798 case (gs_scf_finish)
799
800 ! Here iteration is iter-1, as the clock ticked before SCF_FINISH
801 call scf_finish(this%scf, this%namespace, this%space, this%gr, this%ions, &
802 this%ext_partners, this%st, this%ks, this%hm, iter-1, outp = this%outp)
803
804 case default
805 done = .false.
806 end select
807 class default
808 done = .false.
809 end select
810
811 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
814
815 ! ---------------------------------------------------------
816 logical function electrons_is_tolerance_reached(this, tol) result(converged)
817 class(electrons_t), intent(in) :: this
818 real(real64), intent(in) :: tol
819
821
822 converged = .false.
823
826
827 ! ---------------------------------------------------------
828 subroutine electrons_update_quantity(this, label)
829 class(electrons_t), intent(inout) :: this
830 character(len=*), intent(in) :: label
831
832 class(quantity_t), pointer :: quantity
833
835 call profiling_in(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
836
837 quantity => this%quantities%get(label)
838 if(associated(quantity)) then
839 assert(quantity%updated_on_demand)
840 endif
841
842 select case (label)
843 case ("current")
844 call states_elec_allocate_current(this%st, this%space, this%gr)
845 call current_calculate(this%current_calculator, this%namespace, this%gr, &
846 this%hm, this%space, this%st)
847 case ("dipole")
848 call this%dipole%calculate(this%gr, this%ions, this%st)
849 case default
850 message(1) = "Incompatible quantity: "//trim(label)//"."
851 call messages_fatal(1, namespace=this%namespace)
852 end select
853
854 call profiling_out(trim(this%namespace%get())//":"//"UPDATE_QUANTITY")
856 end subroutine electrons_update_quantity
857
858 ! ---------------------------------------------------------
859 subroutine electrons_init_interaction_as_partner(partner, interaction)
860 class(electrons_t), intent(in) :: partner
861 class(interaction_surrogate_t), intent(inout) :: interaction
862
864
865 select type (interaction)
867 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
868 class default
869 message(1) = "Unsupported interaction."
870 call messages_fatal(1, namespace=partner%namespace)
871 end select
872
875
876 ! ---------------------------------------------------------
877 subroutine electrons_copy_quantities_to_interaction(partner, interaction)
878 class(electrons_t), intent(inout) :: partner
879 class(interaction_surrogate_t), intent(inout) :: interaction
880
882 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
883
884 select type (interaction)
886 assert(allocated(partner%st%current))
887 interaction%partner_field(:,:) = partner%st%current(1:partner%gr%np,:,1)
888 call interaction%do_mapping()
889 class default
890 message(1) = "Unsupported interaction."
891 call messages_fatal(1, namespace=partner%namespace)
892 end select
893
894 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
897
898 ! ---------------------------------------------------------
899 subroutine electrons_output_start(this)
900 class(electrons_t), intent(inout) :: this
901
902 push_sub(electrons_output_start)
903
905 end subroutine electrons_output_start
906
907 ! ---------------------------------------------------------
908 subroutine electrons_output_write(this)
909 class(electrons_t), intent(inout) :: this
910
911 integer :: iter
912
913 push_sub(electrons_output_write)
914 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
915
916 select type (algo => this%algo)
917 class is (propagator_t)
918 iter = this%iteration%counter()
919
920 call td_write_iter(this%td%write_handler, this%namespace, this%space, this%outp, this%gr, &
921 this%st, this%hm, this%ions, this%ext_partners, this%hm%kick, this%ks, algo%dt, iter, this%mc, this%td%recalculate_gs)
922
923 if (this%outp%anything_now(iter)) then ! output
924 call td_write_output(this%namespace, this%space, this%gr, this%st, this%hm, this%ks, &
925 this%outp, this%ions, this%ext_partners, iter, algo%dt)
926 end if
927 end select
928
929 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
931 end subroutine electrons_output_write
932
933 ! ---------------------------------------------------------
934 subroutine electrons_output_finish(this)
935 class(electrons_t), intent(inout) :: this
936
938
940 end subroutine electrons_output_finish
941
942 ! ---------------------------------------------------------
943 logical function electrons_process_is_slave(this) result(is_slave)
944 class(electrons_t), intent(in) :: this
945
947
948 is_slave = multicomm_is_slave(this%mc)
949
951 end function electrons_process_is_slave
952
953 ! ---------------------------------------------------------
955 class(electrons_t), intent(inout) :: this
956 class(propagator_t), intent(in) :: prop
957
958 logical :: stopping
959 logical :: generate
960 logical :: update_energy_
961 integer :: nt
962 real(real64) :: time
963 type(gauge_field_t), pointer :: gfield
964
966 call profiling_in(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
967
968 stopping = .false.
969
970 nt = this%td%iter
971 ! this is the time at the end of the timestep, as required in all routines here
972 time = prop%dt*nt
973 update_energy_ = .true.
974
975 !Apply mask absorbing boundaries
976 if (this%hm%abs_boundaries%abtype == mask_absorbing) call zvmask(this%gr, this%hm, this%st)
977
978 !Photoelectron stuff
979 if (this%td%pesv%calc_spm .or. this%td%pesv%calc_mask .or. this%td%pesv%calc_flux) then
980 call pes_calc(this%td%pesv, this%namespace, this%space, this%gr, this%st, &
981 prop%dt, nt, this%gr%der, this%hm%kpoints, this%ext_partners, stopping)
982 end if
983
984 ! For BOMD, we do not want the lines below to be executed
985 select type(prop)
986 type is(propagator_bomd_t)
987 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
989 return
990 end select
991
992 ! The propagation of the ions and the gauge field is currently done here.
993 ! TODO: this code is to be moved to their own systems at some point
994 generate = .false.
995 if (this%td%ions_dyn%is_active()) then
996 if (.not. this%ions_propagated) then
997 call propagation_ops_elec_propagate_ions_and_cell(this%gr, this%hm, this%st, this%namespace, this%space, &
998 this%td%ions_dyn, this%ions, this%mc, abs(nt*prop%dt), this%td%ions_dyn%ionic_scale*prop%dt)
999 generate = .true.
1000 end if
1001 end if
1002
1003 gfield => list_get_gauge_field(this%ext_partners)
1004 if(associated(gfield)) then
1005 if (gauge_field_is_propagated(gfield) .and. .not. this%ions_propagated) then
1007 end if
1008 end if
1009
1010 if (generate .or. this%ions%has_time_dependent_species()) then
1011 call hamiltonian_elec_epot_generate(this%hm, this%namespace, this%space, this%gr, this%ions, &
1012 this%ext_partners, this%st, time = abs(nt*prop%dt))
1013 end if
1014
1015 call v_ks_calc(this%ks, this%namespace, this%space, this%hm, this%st, this%ions, this%ext_partners, &
1016 calc_eigenval = update_energy_, time = abs(nt*prop%dt), calc_energy = update_energy_)
1017
1018 if (update_energy_) then
1019 call energy_calc_total(this%namespace, this%space, this%hm, this%gr, this%st, this%ext_partners, iunit = -1)
1020 end if
1021
1022 ! Recalculate forces, update velocities...
1023 if (this%td%ions_dyn%ions_move() .or. this%outp%what(option__output__forces) &
1024 .or. this%td%write_handler%out(out_separate_forces)%write) then
1025 call forces_calculate(this%gr, this%namespace, this%ions, this%hm, this%ext_partners, &
1026 this%st, this%ks, t = abs(nt*prop%dt), dt = prop%dt)
1027 end if
1028
1029 if (this%td%ions_dyn%cell_relax() .or. this%outp%what(option__output__stress)) then
1030 call stress_calculate(this%namespace, this%gr, this%hm, this%st, this%ions, this%ks, this%ext_partners)
1031 end if
1032
1033 if(this%td%ions_dyn%is_active()) then
1034 call ion_dynamics_propagate_vel(this%td%ions_dyn, this%ions, atoms_moved = generate)
1035 call this%ions%update_kinetic_energy()
1036 end if
1037
1038 if(associated(gfield)) then
1039 if(gauge_field_is_propagated(gfield)) then
1040 if(abs(this%ks%xc%kernel_lrc_alpha)>m_epsilon) then
1041 call gauge_field_get_force(gfield, this%gr, this%st%d%spin_channels, this%st%current, &
1042 this%ks%xc%kernel_lrc_alpha, this%ks%xc%kernel_proca_a_zero, this%ks%xc%kernel_proca_a_one)
1043 else
1044 call gauge_field_get_force(gfield, this%gr, this%st%d%spin_channels, this%st%current)
1045 endif
1047 end if
1048 end if
1050 !We update the occupation matrices
1051 call lda_u_update_occ_matrices(this%hm%lda_u, this%namespace, this%gr, this%st, this%hm%phase, this%hm%energy)
1052
1053 ! this is needed to be compatible with the code in td_*
1054 this%td%iter = this%td%iter + 1
1055
1056 call profiling_out(trim(this%namespace%get())//":"//"END_OF_TIMESTEP")
1059
1060 ! ---------------------------------------------------------
1061 subroutine electrons_restart_write_data(this)
1062 class(electrons_t), intent(inout) :: this
1063
1064 integer :: ierr
1065
1067 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
1068
1069 select type (algo => this%algo)
1070 class is (propagator_t)
1071 call td_write_data(this%td%write_handler)
1072 call td_dump(this%td, this%namespace, this%space, this%gr, this%st, this%hm, &
1073 this%ks, this%ext_partners, this%iteration%counter(), ierr)
1074 if (ierr /= 0) then
1075 message(1) = "Unable to write time-dependent restart information."
1076 call messages_warning(1, namespace=this%namespace)
1077 end if
1078
1079 ! TODO: this is here because of legacy reasons and should be moved to the output framework
1080 call pes_output(this%td%pesv, this%namespace, this%space, this%gr, this%st, this%iteration%counter(), &
1081 this%outp, algo%dt, this%ions)
1082 end select
1083
1084 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
1086 end subroutine electrons_restart_write_data
1087
1088 ! ---------------------------------------------------------
1089 ! this function returns true if restart data could be read
1090 logical function electrons_restart_read_data(this)
1091 class(electrons_t), intent(inout) :: this
1092
1093 logical :: from_scratch
1094
1096 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
1097
1098 select type (algo => this%algo)
1099 class is (propagator_t)
1100 from_scratch = .false.
1101 call td_load_restart_from_td(this%td, this%namespace, this%space, this%mc, this%gr, &
1102 this%ext_partners, this%st, this%ks, this%hm, from_scratch)
1103 call td_set_from_scratch(this%td, from_scratch)
1104
1105 class is (minimizer_algorithm_t)
1106 from_scratch = .false.
1107 call electrons_gs_load_from_restart(this%namespace, this%scf, this%gr, this%mc, this%st, this%hm, &
1108 this%ks, this%space, this%ions, this%ext_partners,from_scratch)
1109
1110 ! electrons_gs_initialize still knows about fromScratch.
1111 assert(.false.)
1112 end select
1113
1114 if (from_scratch) then
1115 ! restart data could not be loaded
1117 else
1118 ! restart data could be loaded
1120 end if
1121
1122 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
1124 end function electrons_restart_read_data
1125
1126 !----------------------------------------------------------
1127 subroutine electrons_update_kinetic_energy(this)
1128 class(electrons_t), intent(inout) :: this
1129
1131
1132 if (states_are_real(this%st)) then
1133 this%kinetic_energy = denergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1134 else
1135 this%kinetic_energy = zenergy_calc_electronic(this%namespace, this%hm, this%gr%der, this%st, terms = term_kinetic)
1136 end if
1137
1139
1140 end subroutine electrons_update_kinetic_energy
1141
1142 ! ---------------------------------------------------------
1143 subroutine get_fields_from_interaction(this, time)
1144 class(electrons_t), intent(inout) :: this
1145 real(real64), intent(in) :: time
1146
1147 type(interaction_iterator_t) :: iter
1148 real(real64), allocatable :: field_tmp(:, :)
1149
1151
1152 if (this%hm%mxll%coupling_mode == no_maxwell_coupling) then
1154 return
1155 end if
1157 safe_allocate(field_tmp(1:this%gr%np, 1:this%gr%box%dim))
1158 this%hm%mxll%e_field = m_zero
1159 this%hm%mxll%b_field = m_zero
1160 this%hm%mxll%vec_pot = m_zero
1161
1162 ! interpolate field from interaction
1163 call iter%start(this%interactions)
1164 do while (iter%has_next())
1165 select type (interaction => iter%get_next())
1166 class is (mxll_e_field_to_matter_t)
1167 call interaction%interpolate(time, field_tmp)
1168 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%e_field)
1169 class is (mxll_vec_pot_to_matter_t)
1170 call interaction%interpolate(time, field_tmp)
1171 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%vec_pot)
1172 class is (mxll_b_field_to_matter_t)
1173 call interaction%interpolate(time, field_tmp)
1174 call lalg_axpy(this%gr%np, 3, m_one, field_tmp, this%hm%mxll%b_field)
1175 end select
1176 end do
1177
1178 safe_deallocate_a(field_tmp)
1180
1181 end subroutine get_fields_from_interaction
1182
1183
1185 subroutine electrons_ground_state_run_system(sys, from_scratch)
1186 class(electrons_t), intent(inout) :: sys
1187 logical, intent(inout) :: from_scratch
1188
1190
1191 call electrons_ground_state_run(sys%namespace, sys%mc, sys%gr, sys%ions, &
1192 sys%ext_partners, sys%st, sys%ks, sys%hm, sys%outp, sys%space, from_scratch)
1193
1195
1197
1198
1199 subroutine electrons_finalize(sys)
1200 type(electrons_t), intent(inout) :: sys
1201
1202 type(partner_iterator_t) :: iter
1203 class(interaction_partner_t), pointer :: partner
1204
1205 push_sub(electrons_finalize)
1206
1207 if (associated(sys%algo)) then
1208 select type (algo => sys%algo)
1209 class is (propagator_t)
1210 call td_end_run(sys%td, sys%st, sys%hm)
1211 call td_end(sys%td)
1212 class is(minimizer_algorithm_t)
1213 call electrons_gs_cleanup(sys%ks, sys%scf, sys%rdm, sys%st, sys%hm)
1214 end select
1215 end if
1216
1217 if (sys%ks%theory_level /= independent_particles) then
1218 call poisson_async_end(sys%hm%psolver, sys%mc)
1219 end if
1220
1221 call iter%start(sys%ext_partners)
1222 do while (iter%has_next())
1223 partner => iter%get_next()
1224 safe_deallocate_p(partner)
1225 end do
1226 call sys%ext_partners%empty()
1227
1228 safe_deallocate_p(sys%xc_interaction)
1229
1230 call hamiltonian_elec_end(sys%hm)
1231
1232 nullify(sys%gfield)
1233 nullify(sys%lasers)
1234
1235 call multicomm_end(sys%mc)
1236
1237 call xc_oep_photon_end(sys%ks%oep_photon)
1238 if (sys%ks%has_photons) then
1239 call mf_end(sys%ks%pt_mx)
1240 end if
1241
1242 call sys%dipole%end()
1243
1244 call v_ks_end(sys%ks)
1245
1246 call states_elec_end(sys%st)
1247
1248 deallocate(sys%ions)
1249 safe_deallocate_p(sys%photons)
1250
1251 call kpoints_end(sys%kpoints)
1252
1253 call grid_end(sys%gr)
1254
1255 call system_end(sys)
1256
1257 pop_sub(electrons_finalize)
1258 end subroutine electrons_finalize
1259
1260
1261end module electrons_oct_m
1262
1263!! Local Variables:
1264!! mode: f90
1265!! coding: utf-8
1266!! 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_allocate_wavefunctions(namespace, gr, st, hm, scf, ks, ions)
subroutine, public electrons_gs_initialize(namespace, scf, rdm, gr, mc, st, hm, ions, ks, space, ext_partners, fromScratch)
subroutine, public electrons_gs_load_from_restart(namespace, scf, gr, mc, st, hm, ks, space, ions, ext_partners, fromScratch)
subroutine, public electrons_gs_cleanup(ks, scf, rdm, st, hm)
subroutine electrons_initialize(this)
Definition: electrons.F90:669
logical function electrons_restart_read_data(this)
Definition: electrons.F90:1186
subroutine electrons_init_parallelization(this, grp)
Definition: electrons.F90:443
logical function electrons_process_is_slave(this)
Definition: electrons.F90:1039
subroutine electrons_init_interaction(this, interaction)
Definition: electrons.F90:379
subroutine electrons_finalize(sys)
Definition: electrons.F90:1295
subroutine electrons_exec_end_of_timestep_tasks(this, prop)
Definition: electrons.F90:1050
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:1004
subroutine get_fields_from_interaction(this, time)
Definition: electrons.F90:1239
subroutine electrons_algorithm_start(this)
Definition: electrons.F90:692
subroutine electrons_output_finish(this)
Definition: electrons.F90:1030
subroutine electrons_output_start(this)
Definition: electrons.F90:995
subroutine electrons_init_interaction_as_partner(partner, interaction)
Definition: electrons.F90:955
subroutine electrons_ground_state_run_system(sys, from_scratch)
Run a ground state calculation for a system of electrons.
Definition: electrons.F90:1281
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:1223
logical function electrons_is_tolerance_reached(this, tol)
Definition: electrons.F90:912
subroutine electrons_copy_quantities_to_interaction(partner, interaction)
Definition: electrons.F90:973
subroutine electrons_restart_write_data(this)
Definition: electrons.F90:1157
subroutine electrons_update_quantity(this, label)
Definition: electrons.F90:924
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:340
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, proca_a_zero, proca_a_one)
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:193
real(real64), parameter, public m_zero
Definition: global.F90:191
integer, parameter, public independent_particles
Theory level.
Definition: global.F90:237
integer, parameter, public generalized_kohn_sham_dft
Definition: global.F90:237
integer, parameter, public kohn_sham_dft
Definition: global.F90:237
real(real64), parameter, public m_epsilon
Definition: global.F90:207
real(real64), parameter, public m_half
Definition: global.F90:197
real(real64), parameter, public m_one
Definition: global.F90:192
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:471
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:499
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.
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, phase, energy)
Definition: lda_u.F90:798
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: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:383
real(real64) pure function, public mesh_global_memory(mesh)
Definition: mesh.F90:788
real(real64) pure function, public mesh_local_memory(mesh)
Definition: mesh.F90:799
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1023
subroutine, public messages_new_line()
Definition: messages.F90:1112
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1063
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
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:455
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:615
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
subroutine, public scf_finish(scf, namespace, space, gr, ions, ext_partners, st, ks, hm, iter, outp, iters_done)
Definition: scf.F90:1255
subroutine, public scf_start(scf, namespace, gr, ions, st, ks, hm, outp, verbosity)
Preparation of the SCF cycle.
Definition: scf.F90:656
integer, parameter, public verb_compact
Definition: scf.F90:205
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:255
subroutine, public scf_end(scf)
Definition: scf.F90:525
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:799
subroutine, public scf_iter(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, iter, outp, restart_dump)
Definition: scf.F90:842
logical function, public scf_iter_finish(scf, namespace, space, gr, ions, st, ks, hm, iter, outp, iters_done)
Definition: scf.F90:1176
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:1151
subroutine, public system_new_algorithm(this, factory)
Definition: system.F90:947
Definition: td.F90:116
subroutine, public td_end(td)
Definition: td.F90:632
subroutine, public td_load_restart_from_gs(td, namespace, space, mc, gr, ext_partners, st, ks, hm)
Definition: td.F90:1199
subroutine, public td_end_run(td, st, hm)
Definition: td.F90:651
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:1541
subroutine, public td_set_from_scratch(td, from_scratch)
Definition: td.F90:1552
subroutine, public td_dump(td, namespace, space, gr, st, hm, ks, ext_partners, iter, ierr)
Definition: td.F90:1330
subroutine, public td_init_gaugefield(td, namespace, gr, st, ks, hm, ext_partners, space)
Definition: td.F90:601
subroutine, public td_init_with_wavefunctions(td, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, from_scratch)
Definition: td.F90:883
subroutine, public td_load_restart_from_td(td, namespace, space, mc, gr, ext_partners, st, ks, hm, from_scratch)
Definition: td.F90:1163
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:628
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:749
subroutine, public v_ks_init(ks, namespace, gr, st, ions, mc, space, kpoints)
Definition: v_ks.F90:254
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:144
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)