Octopus
rdmft.F90
Go to the documentation of this file.
1!! Copyright (C) 2012-2019 I. Theophilou, N. Helbig
2!! Copyright (C) 2019 F. Buchholz, M. Oliveira
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module rdmft_oct_m
23 use debug_oct_m
30 use energy_oct_m
32 use global_oct_m
33 use grid_oct_m
37 use io_oct_m
39 use ions_oct_m
40 use, intrinsic :: iso_fortran_env
43 use loct_oct_m
44 use math_oct_m
45 use mesh_oct_m
49 use mpi_oct_m
52 use output_oct_m
55 use parser_oct_m
60 use space_oct_m
65 use unit_oct_m
67 use v_ks_oct_m
68 use xc_oep_oct_m
70
71 implicit none
72
73 private
74 public :: &
75 rdm_t, &
76 rdmft_init, &
77 rdmft_end, &
79
80 type rdm_t
81 private
82 type(eigensolver_t) :: eigens
83 integer :: max_iter
84 integer :: iter
85 integer :: nst
86 integer :: n_twoint !number of unique two electron integrals
87 logical :: do_basis
88 logical :: hf
89 real(real64) :: mu
90 real(real64) :: occsum
91 real(real64) :: qtot
92 real(real64) :: scale_f
93 real(real64) :: toler
94 real(real64) :: conv_ener
95 real(real64) :: maxFO
96 real(real64) :: tolerFO
97
98 real(real64), allocatable :: eone(:)
99 real(real64), allocatable :: eone_int(:, :)
100 real(real64), allocatable :: twoint(:)
101 real(real64), allocatable :: hartree(:, :)
102 real(real64), allocatable :: exchange(:, :)
103 real(real64), allocatable :: evalues(:)
104 real(real64), allocatable :: vecnat(:, :)
105 real(real64), allocatable :: Coul(:,:,:)
106 real(real64), allocatable :: Exch(:,:,:)
107
108 integer, allocatable :: i_index(:, :)
109 integer, allocatable :: j_index(:, :)
110 integer, allocatable :: k_index(:, :)
111 integer, allocatable :: l_index(:, :)
112 end type rdm_t
113
114 type(rdm_t), pointer :: rdm_ptr
115
116contains
118 ! ---------------------------------------------------------
119 subroutine rdmft_init(rdm, namespace, gr, st, hm, mc, space, fromScratch)
120 type(rdm_t), intent(out) :: rdm
121 type(namespace_t), intent(in) :: namespace
122 type(grid_t), intent(inout) :: gr
123 type(states_elec_t), intent(in) :: st
124 type(hamiltonian_elec_t), intent(in) :: hm
125 type(multicomm_t), intent(in) :: mc
126 class(space_t), intent(in) :: space
127 logical, intent(in) :: fromScratch
128
129 push_sub(rdmft_init)
130
131 if(st%nst < st%qtot + 1) then
132 message(1) = "Too few states to run RDMFT calculation"
133 message(2) = "Number of states should be at least the number of electrons plus one"
134 call messages_fatal(2, namespace=namespace)
135 end if
136
137 if (states_are_complex(st)) then
138 call messages_not_implemented("Complex states for RDMFT", namespace=namespace)
139 end if
140
141 ! The documentation for the variable is found in scf_init.
142 call parse_variable(namespace, 'MaximumIter', 200, rdm%max_iter)
143
144 !%Variable RDMTolerance
145 !%Type float
146 !%Default 1e-7 Ha
147 !%Section SCF::RDMFT
148 !%Description
149 !% Convergence criterion for stopping the occupation numbers minimization. Minimization is
150 !% stopped when all derivatives of the energy wrt. each occupation number
151 !% are smaller than this criterion. The bisection for finding the correct mu that is needed
152 !% for the occupation number minimization also stops according to this criterion.
153 !%End
154 call parse_variable(namespace, 'RDMTolerance', 1.0e-7_real64, rdm%toler)
155
156 !%Variable RDMToleranceFO
157 !%Type float
158 !%Default 1e-4 Ha
159 !%Section SCF::RDMFT
160 !%Description
161 !% Convergence criterion for stopping the diagonalization of the Fock matrix in the Piris method.
162 !% Orbital minimization is stopped when all off-diagonal ellements of the Fock matrix
163 !% are smaller than this criterion.
164 !%End
165 call parse_variable(namespace, 'RDMToleranceFO', 1.0e-4_real64, rdm%tolerFO)
166
167 !%Variable RDMConvEner
168 !%Type float
169 !%Default 1e-6 Ha
170 !%Section SCF::RDMFT
171 !%Description
172 !% Convergence criterion for stopping the overall minimization of the energy with
173 !% respect to occupation numbers and the orbitals. The minimization of the
174 !% energy stops when the total energy difference between two subsequent
175 !% minimizations of the energy with respect to the occupation numbers and the
176 !% orbitals is smaller than this criterion. It is also used to exit the orbital minimization.
177 !%End
178 call parse_variable(namespace, 'RDMConvEner', 1.0e-7_real64, rdm%conv_ener)
180 !%Variable RDMBasis
181 !%Type logical
182 !%Default yes
183 !%Section SCF::RDMFT
184 !%Description
185 !% If true, all the energy terms and corresponding derivatives involved in RDMFT will
186 !% not be calculated on the grid but on the basis of the initial orbitals
187 !%End
188 call parse_variable(namespace, 'RDMBasis',.true., rdm%do_basis)
190 if (rdm%do_basis .and. fromscratch) then
191 call messages_write("RDMFT calculations with RDMBasis = yes cannot be started FromScratch", new_line=.true.)
192 call messages_write("Run a calculation for independent particles first")
193 call messages_fatal(namespace=namespace)
194 end if
196 !%Variable RDMHartreeFock
197 !%Type logical
198 !%Default no
199 !%Section SCF::RDMFT
200 !%Description
201 !% If true, the code simulates a HF calculation, by omitting the occ.num. optimization
202 !% can be used for test reasons
203 !%End
204 call parse_variable(namespace, 'RDMHartreeFock',.false., rdm%hf)
206 rdm%nst = st%nst
207 if (rdm%do_basis) then
208 rdm%n_twoint = rdm%nst*(rdm%nst + 1)*(rdm%nst**2 + rdm%nst + 2)/8
209 safe_allocate(rdm%eone_int(1:rdm%nst, 1:rdm%nst))
210 safe_allocate(rdm%twoint(1:rdm%n_twoint))
211 safe_allocate(rdm%i_index(1:2,1:rdm%n_twoint))
212 safe_allocate(rdm%j_index(1:2,1:rdm%n_twoint))
213 safe_allocate(rdm%k_index(1:2,1:rdm%n_twoint))
214 safe_allocate(rdm%l_index(1:2,1:rdm%n_twoint))
215 safe_allocate(rdm%vecnat(1:rdm%nst, 1:rdm%nst))
216 safe_allocate(rdm%Coul(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
217 safe_allocate(rdm%Exch(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
218 rdm%eone_int = m_zero
219 rdm%twoint = m_zero
220 rdm%vecnat(:, :) = diagonal_matrix(rdm%nst, m_one)
221 rdm%i_index = m_zero
222 rdm%j_index = m_zero
223 rdm%k_index = m_zero
224 rdm%l_index = m_zero
225 rdm%Coul = m_zero
226 rdm%Exch = m_zero
227 else
228 ! initialize eigensolver.
229 call eigensolver_init(rdm%eigens, namespace, gr, st, hm, mc, space)
230 end if
231
232 safe_allocate(rdm%eone(1:rdm%nst))
233 safe_allocate(rdm%hartree(1:rdm%nst, 1:rdm%nst))
234 safe_allocate(rdm%exchange(1:rdm%nst, 1:rdm%nst))
235 safe_allocate(rdm%evalues(1:rdm%nst))
236
237 rdm%eone = m_zero
238 rdm%hartree = m_zero
239 rdm%exchange = m_zero
240 rdm%evalues = m_zero
241 rdm%mu = m_two*st%eigenval(max(int(st%qtot*m_half), 1), 1)
242 rdm%qtot = st%qtot
243 rdm%occsum = m_zero
244 rdm%scale_f = 1e-2_real64
245 rdm%maxFO = m_zero
246 rdm%iter = 0
247
248 pop_sub(rdmft_init)
249 end subroutine rdmft_init
250
251 ! ----------------------------------------
252
253 subroutine rdmft_end(rdm)
254 type(rdm_t), intent(inout) :: rdm
255
256 push_sub(rdmft_end)
257
258 safe_deallocate_a(rdm%evalues)
259 safe_deallocate_a(rdm%eone)
260 safe_deallocate_a(rdm%hartree)
261 safe_deallocate_a(rdm%exchange)
262
263 if (rdm%do_basis) then
264 safe_deallocate_a(rdm%eone_int)
265 safe_deallocate_a(rdm%twoint)
266 safe_deallocate_a(rdm%i_index)
267 safe_deallocate_a(rdm%j_index)
268 safe_deallocate_a(rdm%k_index)
269 safe_deallocate_a(rdm%l_index)
270 safe_deallocate_a(rdm%vecnat)
271 safe_deallocate_a(rdm%Coul)
272 safe_deallocate_a(rdm%Exch)
273 else
274 call eigensolver_end(rdm%eigens)
275 end if
276
277 pop_sub(rdmft_end)
278 end subroutine rdmft_end
279
280 ! ----------------------------------------
281
282 ! scf for the occupation numbers and the natural orbitals
283 subroutine scf_rdmft(rdm, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
284 type(rdm_t), intent(inout) :: rdm
285 type(namespace_t), intent(in) :: namespace
286 type(electron_space_t), intent(in) :: space
287 type(multicomm_t), intent(in) :: mc
288 type(grid_t), intent(in) :: gr
289 type(ions_t), intent(in) :: ions
290 type(partner_list_t), intent(in) :: ext_partners
291 type(states_elec_t), intent(inout) :: st
292 type(v_ks_t), intent(inout) :: ks
293 type(hamiltonian_elec_t), intent(inout) :: hm
294 type(output_t), intent(in) :: outp
295 type(restart_t), intent(in) :: restart_dump
296
297 type(states_elec_t) :: states_save
298 integer :: iter, icount, ip, ist, ierr, maxcount, iorb
299 integer(int64) :: what_i
300 real(real64) :: energy, energy_dif, energy_old, energy_occ, xpos, xneg, rel_ener
301 real(real64), allocatable :: dpsi(:, :), dpsi2(:, :)
302 logical :: conv
303 character(len=MAX_PATH_LEN) :: dirname
304
305 push_sub(scf_rdmft)
306
307 if (hm%d%ispin /= 1) then
308 call messages_not_implemented("RDMFT exchange function not yet implemented for spin_polarized or spinors", &
309 namespace=namespace)
310 end if
311
312 ! problem is about k-points for exchange
313 if (space%is_periodic()) then
314 call messages_not_implemented("Periodic system calculations for RDMFT", namespace=namespace)
315 end if
316
317 ! exchange routine needs all states on each processor currently
318 if(st%parallel_in_states) then
319 call messages_not_implemented("RDMFT parallel in states", namespace=namespace)
320 end if
321
322 ! two_body_me and the exchange operator need its Poisson solver in double precision
323 if (hm%exxop%compute_single_precision) then
324 call messages_not_implemented("RDMFT with ExchangeSinglePrecision", namespace=namespace)
325 end if
326
327 call messages_print_with_emphasis(msg='RDMFT Calculation', namespace=namespace)
328 call messages_print_var_value('RDMBasis', rdm%do_basis, namespace=namespace)
329
330 !set initial values
331 energy_old = 1.0e20_real64
332 xpos = m_zero
333 xneg = m_zero
334 energy = m_zero
335 if (.not. rdm%do_basis) then
336 maxcount = 1 !still needs to be checked
337 else
338 maxcount = 50
339 !precalculate matrix elements in basis
340 write(message(1),'(a)') 'Calculating Coulomb and exchange matrix elements in basis'
341 write(message(2),'(a)') '--this may take a while--'
342 call messages_info(2, namespace=namespace)
343
344 call two_body_me(gr, st, space, namespace, hm%kpoints, hm%exxop%psolver, 1, st%nst, rdm%i_index, rdm%j_index, rdm%k_index, &
345 rdm%l_index, rdm%twoint)
346 call rdm_integrals(rdm, namespace, hm, st, gr)
347 call sum_integrals(rdm)
348 endif
349
350 ! Start the actual minimization, first step is minimization of occupation numbers
351 ! Orbital minimization is according to Piris and Ugalde, Vol. 30, No. 13, J. Comput. Chem. (scf_orb) or
352 ! using conjugated gradient (scf_orb_cg)
353 conv = .false.
354 do iter = 1, rdm%max_iter
355 rdm%iter = rdm%iter + 1
356 write(message(1), '(a)') '**********************************************************************'
357 write(message(2),'(a, i4)') 'Iteration:', iter
358 call messages_info(2, namespace=namespace)
359 ! occupation number optimization unless we are doing Hartree-Fock
360 if (rdm%hf) then
361 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
362 else
363 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
364 end if
365 ! orbital optimization
366 write(message(1), '(a)') 'Optimization of natural orbitals'
367 call messages_info(1, namespace=namespace)
368 do icount = 1, maxcount
369 if (rdm%do_basis) then
370 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
371 else
372 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
373 end if
374 energy_dif = energy - energy_old
375 energy_old = energy
376 if (rdm%do_basis) then
377 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO) exit
378 if (energy_dif < m_zero) then
379 xneg = xneg + 1
380 else
381 xpos = xpos + 1
382 end if
383 if (xneg > 1.5e0_real64*xpos) then
384 rdm%scale_f = 1.01_real64*rdm%scale_f
385 elseif (xneg < 1.1e0_real64*xpos) then
386 rdm%scale_f = 0.95_real64* rdm%scale_f
387 end if
388 endif !rdm%do_basis
389 end do !icount
390 xneg = m_zero
391 xpos = m_zero
392
393 rel_ener = abs(energy_occ-energy)/abs(energy)
394
395 write(message(1),'(a,11x,es20.10)') 'Total energy:', units_from_atomic(units_out%energy,energy + hm%ep%eii)
396 write(message(2),'(a,1x,es20.10)') 'Rel. energy difference:', rel_ener
397 call messages_info(2, namespace=namespace)
398
399 if (.not. rdm%hf .and. rdm%do_basis) then
400 write(message(1),'(a,18x,es20.10)') 'Max F0:', rdm%maxFO
401 call messages_info(1, namespace=namespace)
402 end if
403
404
405 if (rdm%do_basis) then
406 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
407 else
408 conv = rel_ener < rdm%conv_ener
409 endif
410
411 !Is this still okay or does it restrict the possible convergence? FB: Does this makes sense at all?
412 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
413
414 ! save restart information
415 if ((conv .or. restart_walltime_period_alarm(mc%master_comm) .or. iter == rdm%max_iter)) then
416 if (rdm%do_basis) then
417 call states_elec_copy(states_save, st)
418 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
419 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
420 do iorb = 1, st%nst
421 dpsi = m_zero
422 do ist = 1, st%nst
423 call states_elec_get_state(st, gr, ist, 1, dpsi2)
424 do ip = 1, gr%np
425 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
426 end do
427 end do
428 call states_elec_set_state(states_save, gr, iorb, 1, dpsi)
429 end do
430 call density_calc(states_save, gr, states_save%rho)
431 ! if other quantities besides the densities and the states are needed they also have to be recalculated here!
432 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
433
434 if (conv .or. iter == rdm%max_iter) then
435 call states_elec_end(st)
436 call states_elec_copy(st, states_save)
437 end if
438
439 call states_elec_end(states_save)
440
441 safe_deallocate_a(dpsi)
442 safe_deallocate_a(dpsi2)
443 else
444 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
445
446 ! calculate maxFO for cg-solver
447 if (.not. rdm%hf) then
448 call calc_maxfo (namespace, hm, st, gr, rdm)
449 write(message(1),'(a,18x,es20.10)') 'Max F0:', rdm%maxFO
450 call messages_info(1, namespace=namespace)
451 end if
452 endif
453
454 if (ierr /= 0) then
455 message(1) = 'Unable to write states wavefunctions.'
456 call messages_warning(1, namespace=namespace)
457 end if
458
459 endif
460
461 ! write output for iterations if requested
462 if (any(outp%what) .and. outp%duringscf) then
463 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
464 if (outp%what_now(what_i, iter)) then
465 write(dirname,'(a,a,i4.4)') trim(outp%iter_dir), "scf.", iter
466 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
467 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
468 call scf_write_static(dirname, "info")
469 exit
470 end if
471 end do
472 end if
473
474 if (conv) exit
475 end do
476
477 if(conv) then
478 write(message(1),'(a,i3,a)') 'The calculation converged after ',rdm%iter,' iterations'
479 write(message(2),'(a,9x,es20.10)') 'The total energy is ', units_from_atomic(units_out%energy,energy + hm%ep%eii)
480 call messages_info(2, namespace=namespace)
481 else
482 write(message(1),'(a,i3,a)') 'The calculation did not converge after ', iter-1, ' iterations '
483 write(message(2),'(a,es15.5)') 'Relative energy difference between the last two iterations ', rel_ener
484 write(message(3),'(a,es15.5)') 'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
485 call messages_info(3, namespace=namespace)
486 end if
487
488 call scf_write_static(static_dir, "info")
489 call output_all(outp, namespace, space, static_dir, gr, ions, -1, st, hm, ks)
490 call output_modelmb(outp, namespace, space, static_dir, gr, ions, -1, st)
491
492 pop_sub(scf_rdmft)
493
494 contains
495 ! ---------------------------------------------------------
496 subroutine scf_write_static(dir, fname)
497 character(len=*), intent(in) :: dir, fname
498
499 integer :: iunit, ist
500 real(real64), allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
501
503
504 safe_allocate(photon_number_state(1:st%nst))
505 safe_allocate(ekin_state(1:st%nst))
506 safe_allocate(epot_state(1:st%nst))
507
508 if(st%system_grp%is_root()) then
509 call io_mkdir(dir, namespace)
510 iunit = io_open(trim(dir) // "/" // trim(fname), namespace, action='write')
511
512 call grid_write_info(gr, iunit=iunit)
513
514 call v_ks_write_info(ks, iunit=iunit)
515
516 if (rdm%do_basis) then
517 write(iunit, '(a)')'Orbital optimization with [basis set]'
518 else
519 write(iunit, '(a)')'Orbital optimization with [conjugated gradients]'
520 end if
521 write(iunit, '(1x)')
522
523 if (rdm%hf) then
524 write(iunit, '(a)')'Hartree Fock calculation'
525 write(iunit, '(1x)')
526 end if
527
528 if (hm%psolver%is_dressed) then
529 write(iunit, '(a)')'Dressed state calculation'
530 call photon_mode_write_info(hm%psolver%photons, iunit=iunit)
531 write(iunit, '(1x)')
532 end if
533
534 ! scf information
535 if(conv) then
536 write(iunit, '(a, i4, a)')'SCF converged in ', iter, ' iterations'
537 else
538 write(iunit, '(a)') 'SCF *not* converged!'
539 end if
540 write(iunit, '(1x)')
541
542 write(iunit, '(3a,es20.10)') 'Total Energy [', trim(units_abbrev(units_out%energy)), ']:', &
543 units_from_atomic(units_out%energy, energy + hm%ep%eii)
544 write(iunit,'(a,1x,f16.12)') 'Sum of occupation numbers:', rdm%occsum
545 else
546 iunit = 0
547 end if
548
549 if (hm%psolver%is_dressed) then
550 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
551 if(st%system_grp%is_root()) then
552 write(iunit,'(a,1x,f14.12)') 'Total mode occupation:', hm%psolver%photons%number(1)
553 end if
554 end if
555
556 if(st%system_grp%is_root()) then
557 if (rdm%max_iter > 0) then
558 write(iunit, '(a)') 'Convergence:'
559 write(iunit, '(6x, a, es15.8)') 'maxFO = ', rdm%maxFO
560 write(iunit, '(6x, a, es15.8)') 'rel_ener = ', rel_ener
561 write(iunit,'(1x)')
562 end if
563 ! otherwise, these values are uninitialized, and unknown.
564 end if
565
566 if (st%system_grp%is_root()) then
567 ! Write header
568 write(iunit,'(a)') 'Natural occupation numbers:'
569 write(iunit,'(a4,5x,a12)', advance='no') '#st', 'Occupation'
570 if (.not. rdm%do_basis) write(iunit,'(5x,a12)', advance='no') 'conv'
571 if (hm%psolver%is_dressed) write(iunit,'(3(5x,a12))', advance='no') 'Mode Occ.', '-1/2d^2/dq^2', '1/2w^2q^2'
572 write(iunit,*)
573
574 ! Write values
575 do ist = 1, st%nst
576 write(iunit,'(i4,3x,f14.12)', advance='no') ist, st%occ(ist, 1)
577 if (.not. rdm%do_basis) write(iunit,'(3x,f14.12)', advance='no') rdm%eigens%diff(ist, 1)
578 if (hm%psolver%is_dressed) then
579 write(iunit,'(3(3x,f14.12))', advance='no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
580 end if
581 write(iunit,*)
582 end do
583 end if
584
585 if (st%system_grp%is_root()) then
586 call io_close(iunit)
587 end if
588
589 safe_deallocate_a(photon_number_state)
590 safe_deallocate_a(ekin_state)
591 safe_deallocate_a(epot_state)
592
594 end subroutine scf_write_static
595 end subroutine scf_rdmft
596
597 ! ---------------------------------------------------------
598 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
599 type(namespace_t), intent(in) :: namespace
600 type(rdm_t), intent(inout) :: rdm
601 type(grid_t), intent(in) :: gr
602 type(hamiltonian_elec_t), intent(inout) :: hm
603 type(states_elec_t), intent(inout) :: st
604
605 real(real64), allocatable :: lambda(:, :), FO(:, :)
606 integer :: ist, jst
607
608 push_sub(calc_maxfo)
609
610 safe_allocate(lambda(1:st%nst,1:st%nst))
611 safe_allocate(fo(1:st%nst, 1:st%nst))
612
613 ! calculate FO operator to check Hermiticity of lagrange multiplier matrix (lambda)
614 lambda = m_zero
615 fo = m_zero
616 call construct_lambda(namespace, hm, st, gr, lambda, rdm)
617
618 !Set up FO matrix to check maxFO
619 do ist = 1, st%nst
620 do jst = 1, ist - 1
621 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
622 end do
623 end do
624 rdm%maxFO = maxval(abs(fo))
625
626 safe_deallocate_a(lambda)
627 safe_deallocate_a(fo)
628
629 pop_sub(calc_maxfo)
630 end subroutine calc_maxfo
631
632 ! ---------------------------------------------------------
633 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
634 class(space_t), intent(in) :: space
635 type(grid_t), intent(in) :: gr
636 type(states_elec_t), intent(in) :: st
637 type(photon_mode_t), intent(inout) :: photons
638 real(real64), contiguous, intent(out) :: photon_number_state(:)
639 real(real64), contiguous, intent(out) :: ekin_state(:)
640 real(real64), contiguous, intent(out) :: epot_state(:)
641
642 integer :: ist, dim_photon, ip
643 real(real64) :: q2_exp, laplace_exp
644 real(real64), allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
645
646 push_sub(calc_photon_number)
647
648 ! The photon dimension is always the last
649 dim_photon = space%dim
650
651 safe_allocate(psi(1:gr%np_part, 1))
652 safe_allocate(psi_q2(1:gr%np))
653 safe_allocate(dpsidq(1:gr%np_part))
654 safe_allocate(d2psidq2(1:gr%np))
655
656 photons%number(1) = m_zero
657
658 do ist = 1, st%nst
659 call states_elec_get_state(st, gr, ist, 1, psi)
660
661 ! <phi(ist)|d^2/dq^2|phi(ist)> ~= <phi(ist)| d/dq (d/dq|phi(ist)>)
662 call dderivatives_partial(gr%der, psi(:, 1), dpsidq(:), dim_photon, ghost_update = .true., set_bc = .true.)
663 call dderivatives_partial(gr%der, dpsidq(1:gr%np_part), d2psidq2(:), dim_photon, ghost_update = .true., set_bc = .true.)
664 laplace_exp = dmf_dotp(gr, psi(:, 1), d2psidq2(:))
665 ekin_state(ist) = -m_half*laplace_exp
666
667 ! <phi(ist)|q^2|psi(ist)>= |q|psi(ist)>|^2
668 !$omp parallel do
669 do ip = 1, gr%np
670 psi_q2(ip) = psi(ip, 1) * gr%x_t(ip, dim_photon)**2
671 end do
672 !$omp end parallel do
673 q2_exp = dmf_dotp(gr, psi(:, 1), psi_q2(:))
674 epot_state(ist) = m_half * photons%omega(1)**2 * q2_exp
675
676 !! N_phot(ist)=( <phi_i|H_ph|phi_i>/omega - 0.5 ) / N_elec
677 !! with <phi_i|H_ph|phi_i>=-0.5* <phi(ist)|d^2/dq^2|phi(ist)> + 0.5*omega <phi(ist)|q^2|psi(ist)>
678 photon_number_state(ist) = -m_half*laplace_exp / photons%omega(1) + m_half * photons%omega(1) * q2_exp
679 photon_number_state(ist) = photon_number_state(ist) - m_half
680
681 !! N_phot_total= sum_ist occ_ist*N_phot(ist)
682 photons%number(1) = photons%number(1) + (photon_number_state(ist) + m_half)*st%occ(ist, 1)
683 ! 0.5 must be added again to do the normalization due to the total charge correctly
684 end do
685
686 photons%number(1) = photons%number(1) - st%qtot/m_two
687
688 safe_deallocate_a(psi)
689 safe_deallocate_a(psi_q2)
690 safe_deallocate_a(dpsidq)
691 safe_deallocate_a(d2psidq2)
692
694 end subroutine calc_photon_number
695
696 ! ---------------------------------------------------------
697
698 ! reset occ.num. to 2/0
699 subroutine set_occ_pinning(st)
700 type(states_elec_t), intent(inout) :: st
701
702 real(real64), allocatable :: occin(:, :)
703
704 push_sub(set_occ_pinning)
705
706 safe_allocate(occin(1:st%nst, 1:st%nik))
707
708 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
709 where(occin(:, :) < m_one) occin(:, :) = m_zero
710 where(occin(:, :) > m_one) occin(:, :) = st%smear%el_per_state
711
712 st%occ(:, :) = occin(:, :)
713
714 safe_deallocate_a(occin)
715
716 pop_sub(set_occ_pinning)
717 end subroutine set_occ_pinning
718
719
720 ! ---------------------------------------------------------
721 ! dummy routine for occupation numbers which only calculates the necessary variables for further use
722 ! used in Hartree-Fock mode
723 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
724 type(rdm_t), intent(inout) :: rdm
725 type(namespace_t), intent(in) :: namespace
726 type(grid_t), intent(in) :: gr
727 type(hamiltonian_elec_t), intent(in) :: hm
728 class(space_t), intent(in) :: space
729 type(states_elec_t), intent(inout) :: st
730 real(real64), intent(out) :: energy
731
732 integer :: ist
733
734 push_sub(scf_occ_no)
735
736 write(message(1),'(a)') 'SKIP Optimization of occupation numbers'
737 call messages_info(1, namespace=namespace)
738
739 call set_occ_pinning(st)
740
741 energy = m_zero
742
743 call rdm_derivatives(rdm, namespace, hm, st, gr, space)
744
745 call total_energy_rdm(rdm, st%occ(:,1), energy)
746
747 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
748
749 write(message(1),'(a4,5x,a12)')'#st','Occupation'
750 call messages_info(1, namespace=namespace)
751
752 do ist = 1, st%nst
753 write(message(1),'(i4,3x,f11.9)') ist, st%occ(ist, 1)
754 call messages_info(1, namespace=namespace)
755 end do
756
757 write(message(1),'(a,1x,f13.9)') 'Sum of occupation numbers', rdm%occsum
758 write(message(2),'(a,es20.10)') 'Total energy occ', units_from_atomic(units_out%energy,energy + hm%ep%eii)
759 call messages_info(2, namespace=namespace)
760
761 pop_sub(scf_occ_no)
762 end subroutine scf_occ_no
763
764 ! scf for the occupation numbers
765 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
766 type(rdm_t), target, intent(inout) :: rdm
767 type(namespace_t), intent(in) :: namespace
768 type(grid_t), intent(in) :: gr
769 type(hamiltonian_elec_t), intent(in) :: hm
770 class(space_t), intent(in) :: space
771 type(states_elec_t), intent(inout) :: st
772 real(real64), intent(out) :: energy
773
774 integer :: ist, icycle, ierr
775 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
776 real(real64), allocatable :: occin(:, :)
777 real(real64), parameter :: smallocc = 0.00001_real64
778 real(real64), allocatable :: theta(:)
779 real(real64) :: objective
780 integer, parameter :: max_cycle = 200
781
782 push_sub(scf_occ)
783 call profiling_in("SCF_OCC")
784
785 write(message(1),'(a)') 'Optimization of occupation numbers'
786 call messages_info(1, namespace=namespace)
787
788 safe_allocate(occin(1:st%nst, 1:st%nik))
789 safe_allocate(theta(1:st%nst))
790
791 occin = m_zero
792 theta = m_zero
793 energy = m_zero
795 ! Defines a threshold on occ nums to avoid numerical instabilities.
796 ! Needs to be changed consistently with the same variable in objective_rdmft
797 thresh_occ = 1e-14_real64
798
799 !Initialize the occin. Smallocc is used for numerical stability
800 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
801 where(occin(:, :) < smallocc) occin(:, :) = smallocc
802 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
803
804 !Renormalize the occupation numbers
805 rdm%occsum = st%qtot
806
807 st%occ(:, :) = occin(:, :)
808
809 call rdm_derivatives(rdm, namespace, hm, st, gr, space)
810
811 !finding the chemical potential mu such that the occupation numbers sum up to the number of electrons
812 !bisection to find the root of rdm%occsum-st%qtot=M_ZERO
813 mu1 = rdm%mu !initial guess for mu
814 mu2 = -1.0e-6_real64
815 dinterv = m_half
816
817 ! Set pointer to rdm, so that it is available in the functions called by the minimizer
818 rdm_ptr => rdm
819
820 !use n_j=sin^2(2pi*theta_j) to treat pinned states, minimize for both intial mu
821 theta(:) = asin(sqrt(occin(:, 1)/st%smear%el_per_state))*(m_half/m_pi)
822 call minimize_multidim(minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
823 1e-12_real64, 1e-12_real64, 200, objective_rdmft, write_iter_info_rdmft, objective, ierr)
824 sumgi1 = rdm%occsum - st%qtot
825 rdm%mu = mu2
826 theta(:) = asin(sqrt(occin(:, 1)/st%smear%el_per_state))*(m_half/m_pi)
827 call minimize_multidim(minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
828 1e-12_real64, 1e-12_real64, 200, objective_rdmft, write_iter_info_rdmft, objective, ierr)
829 sumgi2 = rdm%occsum - st%qtot
830
831 ! Adjust the interval between the initial mu to include the root of rdm%occsum-st%qtot=M_ZERO
832 do icycle = 1, max_cycle
833 if (sumgi1*sumgi2 <= m_zero) exit
834 if (sumgi2 > m_zero) then
835 mu2 = mu1
836 sumgi2 = sumgi1
837 mu1 = mu1 - dinterv
838 rdm%mu = mu1
839 theta(:) = asin(sqrt(occin(:, 1)/st%smear%el_per_state))*(m_half/m_pi)
840 call minimize_multidim(minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
841 1e-12_real64, 1e-12_real64, 200, objective_rdmft, write_iter_info_rdmft, objective, ierr)
842 sumgi1 = rdm%occsum - st%qtot
843 else
844 mu1 = mu2
845 sumgi1 = sumgi2
846 mu2 = mu2 + dinterv
847 rdm%mu = mu2
848 theta(:) = asin(sqrt(occin(:, 1)/st%smear%el_per_state))*(m_half/m_pi)
849 call minimize_multidim(minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
850 1e-12_real64, 1e-12_real64, 200, objective_rdmft, write_iter_info_rdmft, objective, ierr)
851 sumgi2 = rdm%occsum - st%qtot
852 end if
853 end do
854
855 do icycle = 1, 50
856 mum = (mu1 + mu2)*m_half
857 rdm%mu = mum
858 theta(:) = asin(sqrt(occin(:, 1)/st%smear%el_per_state))*(m_half/m_pi)
859 call minimize_multidim(minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
860 1e-12_real64, 1e-12_real64, 200, objective_rdmft, write_iter_info_rdmft, objective, ierr)
861 sumgim = rdm%occsum - st%qtot
862
863 if (sumgi1*sumgim < m_zero) then
864 mu2 = mum
865 else
866 mu1 = mum
867 sumgi1 = sumgim
868 end if
869
870 ! check occ.num. threshold again after minimization
871 do ist = 1, st%nst
872 st%occ(ist,1) = m_two*sin(theta(ist)*m_pi*m_two)**2
873 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
874 end do
875
876 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*m_half) < rdm%toler) exit
877 end do
878
879 nullify(rdm_ptr)
880
881 if (icycle >= 50) then
882 write(message(1),'(a,1x,f11.4)') 'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
883 call messages_fatal(1, namespace=namespace)
884 end if
885
886 do ist = 1, st%nst
887 st%occ(ist, 1) = st%smear%el_per_state*sin(theta(ist)*m_pi*m_two)**2
888 end do
889
890 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
891 energy = objective
892
893 write(message(1),'(a4,5x,a12)')'#st','Occupation'
894 call messages_info(1, namespace=namespace)
895
896 do ist = 1, st%nst
897 write(message(1),'(i4,3x,f14.12)') ist, st%occ(ist, 1)
898 call messages_info(1, namespace=namespace)
899 end do
900
901 write(message(1),'(a,3x,f11.9)') 'Sum of occupation numbers: ', rdm%occsum
902 write(message(2),'(a,11x,es20.10)') 'Total energy: ', units_from_atomic(units_out%energy, energy + hm%ep%eii)
903 call messages_info(2, namespace=namespace)
904
905 safe_deallocate_a(occin)
906 safe_deallocate_a(theta)
907
908 call profiling_out("SCF_OCC")
909 pop_sub(scf_occ)
910 end subroutine scf_occ
911
912 ! ---------------------------------------------------------
913 subroutine objective_rdmft(size, theta, objective, getgrad, df)
914 integer, intent(in) :: size
915 real(real64), intent(in) :: theta(size)
916 real(real64), intent(inout) :: objective
917 integer, intent(in) :: getgrad
918 real(real64), intent(inout) :: df(size)
919
920 integer :: ist
921 real(real64) :: thresh_occ, thresh_theta
922 real(real64), allocatable :: dE_dn(:),occ(:)
923
924 push_sub(objective_rdmft)
925
926 assert(size == rdm_ptr%nst)
927
928 safe_allocate(de_dn(1:size))
929 safe_allocate(occ(1:size))
930
931 occ = m_zero
932
933 ! Defines a threshold on occ nums to avoid numerical instabilities.
934 ! Needs to be changed consistently with the same variable in scf_occ
935 thresh_occ = 1e-14_real64
936 thresh_theta = asin(sqrt(thresh_occ/m_two))*(m_half/m_pi)
937
938 do ist = 1, size
939 occ(ist) = m_two*sin(theta(ist)*m_pi*m_two)**2
940 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
941 end do
942
943 rdm_ptr%occsum = sum(occ(1:size))
944
945 !calculate the total energy without nuclei interaction and the energy
946 !derivatives with respect to the occupation numbers
947
948 call total_energy_rdm(rdm_ptr, occ, objective, de_dn)
949 do ist = 1, size
950 if (occ(ist) <= thresh_occ ) then
951 df(ist) = m_four*m_pi*sin(m_four*thresh_theta*m_pi)*(de_dn(ist) - rdm_ptr%mu)
952 else
953 df(ist) = m_four*m_pi*sin(m_four*theta(ist)*m_pi)*(de_dn(ist) - rdm_ptr%mu)
954 end if
955 end do
956 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
957
958 safe_deallocate_a(de_dn)
959 safe_deallocate_a(occ)
960
961 pop_sub(objective_rdmft)
962 end subroutine objective_rdmft
963
964 ! ---------------------------------------------------------
965 subroutine write_iter_info_rdmft(iter, size, energy, maxdr, maxdf, theta)
966 integer, intent(in) :: iter
967 integer, intent(in) :: size
968 real(real64), intent(in) :: energy, maxdr, maxdf
969 real(real64), intent(in) :: theta(size)
970
971 push_sub(write_iter_info_rdmft)
972
973 ! Nothing to do.
974
975 pop_sub(write_iter_info_rdmft)
976 end subroutine write_iter_info_rdmft
977
978 ! scf for the natural orbitals
979 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
980 type(rdm_t), intent(inout) :: rdm
981 type(namespace_t), intent(in) :: namespace
982 type(grid_t), intent(in) :: gr
983 type(states_elec_t), intent(inout) :: st
984 type(hamiltonian_elec_t), intent(in) :: hm
985 class(space_t), intent(in) :: space
986 real(real64), intent(out) :: energy
987
988 integer :: ist, jst
989 real(real64), allocatable :: lambda(:, :), fo(:, :)
990
991 push_sub(scf_orb)
992 call profiling_in("SCF_ORB_BASIS")
993
994 !matrix of Lagrange Multipliers from Equation (8), Piris and Ugalde, Vol. 30, No. 13, J. Comput. Chem.
995 safe_allocate(lambda(1:st%nst,1:st%nst))
996 safe_allocate(fo(1:st%nst, 1:st%nst)) !Generalized Fockian Equation (11)
997
998 lambda = m_zero
999 fo = m_zero
1000
1001 call construct_lambda(namespace, hm, st, gr, lambda, rdm)
1002
1003 !Set up fo matrix
1004 if (rdm%iter==1) then
1005 do ist = 1, st%nst
1006 do jst = 1, ist
1007 fo(ist, jst) = m_half*(lambda(ist, jst) + lambda(jst, ist))
1008 fo(jst, ist) = fo(ist, jst)
1009 end do
1010 end do
1011 else
1012 do ist = 1, st%nst
1013 do jst = 1, ist - 1
1014 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1015 end do
1016 end do
1017 rdm%maxfo = maxval(abs(fo))
1018 do ist = 1, st%nst
1019 fo(ist, ist) = rdm%evalues(ist)
1020 do jst = 1, ist-1
1021 if(abs(fo(jst, ist)) > rdm%scale_f) then
1022 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1023 end if
1024 fo(ist, jst) = fo(jst, ist)
1025 end do
1026 end do
1027 end if
1028
1029 call lalg_eigensolve(st%nst, fo, rdm%evalues)
1030 call assign_eigfunctions(rdm, st, fo)
1031 call sum_integrals(rdm) ! to calculate rdm%Coul and rdm%Exch with the new rdm%vecnat
1032 call rdm_derivatives(rdm, namespace, hm, st, gr, space)
1033 call total_energy_rdm(rdm, st%occ(:,1), energy)
1034
1035 safe_deallocate_a(lambda)
1036 safe_deallocate_a(fo)
1037
1038 call profiling_out("SCF_ORB_BASIS")
1039 pop_sub(scf_orb)
1040 end subroutine scf_orb
1041
1042
1043 !-----------------------------------------------------------------
1044 ! Minimize the total energy wrt. an orbital by conjugate gradient
1045 !-----------------------------------------------------------------
1046 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1047 type(rdm_t), intent(inout) :: rdm
1048 type(namespace_t), intent(in) :: namespace
1049 type(electron_space_t), intent(in) :: space
1050 type(grid_t), intent(in) :: gr
1051 type(ions_t), intent(in) :: ions
1052 type(partner_list_t), intent(in) :: ext_partners
1053 type(states_elec_t), intent(inout) :: st
1054 type(v_ks_t), intent(inout) :: ks
1055 type(hamiltonian_elec_t), intent(inout) :: hm
1056 real(real64), intent(out) :: energy
1057
1058 integer :: ik, ist, maxiter
1059
1061 push_sub(scf_orb_cg)
1062 call profiling_in("CG")
1063
1064 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1065 call hm%update(gr, namespace, space, ext_partners)
1066
1067 rdm%eigens%converged = 0
1068 if(st%system_grp%is_root() .and. .not. debug%info) then
1069 call loct_progress_bar(-1, st%lnst*st%d%kpt%nlocal())
1070 end if
1071 do ik = st%d%kpt%start, st%d%kpt%end
1072 rdm%eigens%matvec = 0
1073 maxiter = rdm%eigens%es_maxiter
1074 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1075 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1076 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1077
1078 if (.not. rdm%eigens%folded_spectrum) then
1079 ! recheck convergence after subspace diagonalization, since states may have reordered (copied from eigensolver_run)
1080 rdm%eigens%converged(ik) = 0
1081 do ist = 1, st%nst
1082 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance) then
1083 rdm%eigens%converged(ik) = ist
1084 else
1085 exit
1086 end if
1087 end do
1088 end if
1089 end do
1090
1091 if(st%system_grp%is_root() .and. .not. debug%info) then
1092 write(stdout, '(1x)')
1093 end if
1094
1095 ! calculate total energy with new states
1096 call density_calc (st, gr, st%rho)
1097 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1098 call hm%update(gr, namespace, space, ext_partners)
1099 call rdm_derivatives(rdm, namespace, hm, st, gr, space)
1100
1101 call total_energy_rdm(rdm, st%occ(:,1), energy)
1102
1103 call profiling_out("CG")
1104 pop_sub(scf_orb_cg)
1105 end subroutine scf_orb_cg
1106
1107
1108 ! ----------------------------------------
1109 ! constructs the Lagrange multiplyers needed for the orbital minimization
1110 subroutine construct_lambda(namespace, hm, st, gr, lambda, rdm)
1111 type(namespace_t), intent(in) :: namespace
1112 type(hamiltonian_elec_t), intent(in) :: hm
1113 type(states_elec_t), intent(inout) :: st
1114 type(grid_t), intent(in) :: gr
1115 real(real64), contiguous, intent(out) :: lambda(:, :)
1116 type(rdm_t), intent(inout) :: rdm
1117
1118 real(real64), allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1119 real(real64), allocatable :: fock(:,:,:), FV(:,:)
1120 integer :: ist, iorb, jorb, jst
1121
1122 push_sub(construct_lambda)
1123
1124 lambda = m_zero
1125
1126 !calculate the Lagrange multiplyer lambda matrix on the grid, Eq. (9), Piris and Ugalde, Vol. 30, No. 13, J. Comput. Chem.
1127 if (.not. rdm%do_basis) then
1128 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1129 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1130 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1131 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1132
1133 do iorb = 1, st%nst
1134 call states_elec_get_state(st, gr, iorb, 1, dpsi)
1135 call dhamiltonian_elec_apply_single(hm, namespace, gr, dpsi, hpsi, iorb, 1)
1136
1137 do jorb = iorb, st%nst
1138 ! calculate <phi_j|H|phi_i> =lam_ji
1139 call states_elec_get_state(st, gr, jorb, 1, dpsi1)
1140 lambda(jorb, iorb) = dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1142 ! calculate <phi_i|H|phi_j>=lam_ij
1143 if (iorb /= jorb ) then
1144 call dhamiltonian_elec_apply_single(hm, namespace, gr, dpsi1, hpsi1, jorb, 1)
1145 lambda(iorb, jorb) = dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1146 end if
1147 end do
1148 end do
1149
1150
1151 else ! calculate the same lambda matrix on the basis
1152 !call sum_integrals(rdm)
1153 safe_allocate(fv(1:st%nst, 1:st%nst))
1154 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1155 fock = m_zero
1156
1157 do iorb = 1, st%nst
1158 do ist = 1, st%nst
1159 do jst = 1, ist
1160 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1161 do jorb = 1, st%nst
1162 !The coefficient of the Exchange term below is only for the Mueller functional
1163 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1164 - sqrt(st%occ(iorb, 1))*sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1165 end do
1166 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1167 end do
1168 end do
1169 end do
1170
1171 ! FV(:,jorb) = fock(:,:,jorb) * vecnat(:,jorb)
1172 do jorb = 1, st%nst
1173 call lalg_gemv(st%nst, st%nst, m_one, fock(:,:,jorb), rdm%vecnat(:, jorb), m_zero, fv(:, jorb))
1174 end do
1175 ! lambda = vecnat^T * FV
1176 call lalg_gemm_cn(st%nst, st%nst, st%nst, m_one, rdm%vecnat, fv, m_zero, lambda)
1177 end if
1178
1179
1180 if (.not. rdm%do_basis) then
1181 safe_deallocate_a(hpsi)
1182 safe_deallocate_a(hpsi1)
1183 safe_deallocate_a(dpsi)
1184 safe_deallocate_a(dpsi1)
1185 else
1186 safe_deallocate_a(fv)
1187 safe_deallocate_a(fock)
1188 end if
1189
1190 pop_sub(construct_lambda)
1191 end subroutine construct_lambda
1192
1193 ! ----------------------------------------
1194
1195 ! finds the new states after the minimization of the orbitals (Piris method)
1196 subroutine assign_eigfunctions(rdm, st, lambda)
1197 type(rdm_t), intent(inout) :: rdm
1198 type(states_elec_t), intent(inout) :: st
1199 real(real64), contiguous, intent(in) :: lambda(:, :)
1200
1201 integer :: iorb, jorb, ist
1202 real(real64), allocatable :: vecnat_new(:, :)
1203
1204 push_sub(assign_eigenfunctions)
1206 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1207 do iorb = 1, st%nst
1208 do ist = 1, st%nst
1209 vecnat_new(ist, iorb) = m_zero
1210 do jorb = 1, st%nst
1211 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1212 end do
1213 end do
1214 end do
1215
1216 rdm%vecnat(:, :) = vecnat_new(:, :)
1217
1218 safe_deallocate_a(vecnat_new)
1219
1220 pop_sub(assign_eigenfunctions)
1221 end subroutine assign_eigfunctions
1222
1223 ! --------------------------------------------
1224
1225 ! calculates the total energy when only the occupation numbers are updated
1226 subroutine total_energy_rdm(rdm, occ, energy, dE_dn)
1227 type(rdm_t), intent(in) :: rdm
1228 real(real64), contiguous, intent(in) :: occ(:)
1229 real(real64), intent(out) :: energy
1230 real(real64), contiguous, optional, intent(out) :: dE_dn(:)
1231
1232 integer :: ist
1233 real(real64), allocatable :: V_h(:), V_x(:), sqrt_occ(:)
1234
1235 push_sub(total_energy_rdm)
1236
1237 safe_allocate(v_h(1:rdm%nst))
1238 safe_allocate(v_x(1:rdm%nst))
1239 safe_allocate(sqrt_occ(1:rdm%nst))
1240
1241 energy = m_zero
1242
1243 !Calculate hartree and exchange contribution
1244 !This is only for the Mueller functional and has to be changed
1245 sqrt_occ(1:rdm%nst) = sqrt(occ(1:rdm%nst))
1246 ! V_h = hartree * occ ; V_x = -exchange * sqrt(occ) (beta = 0 overwrites)
1247 call lalg_gemv(rdm%nst, rdm%nst, m_one, rdm%hartree, occ, m_zero, v_h)
1248 call lalg_gemv(rdm%nst, rdm%nst, -m_one, rdm%exchange, sqrt_occ, m_zero, v_x)
1249 do ist = 1, rdm%nst
1250 v_x(ist) = v_x(ist)*m_half/max(sqrt_occ(ist), 1.0e-16_real64)
1251 end do
1252
1253
1254 !Calculate the energy derivative with respect to the occupation numbers
1255 if (present(de_dn)) then
1256 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1257 end if
1258
1259 !Total energy calculation without nuclei interaction
1260 do ist = 1, rdm%nst
1261 energy = energy + occ(ist)*rdm%eone(ist) &
1262 + m_half*occ(ist)*v_h(ist) &
1263 + occ(ist)*v_x(ist)
1264 end do
1265
1266 safe_deallocate_a(sqrt_occ)
1267 safe_deallocate_a(v_h)
1268 safe_deallocate_a(v_x)
1269
1270 pop_sub(total_energy_rdm)
1271 end subroutine total_energy_rdm
1272
1273 ! ----------------------------------------
1274 ! calculates the derivatives of the energy terms with respect to the occupation numbers
1275 subroutine rdm_derivatives(rdm, namespace, hm, st, gr, space)
1276 type(rdm_t), intent(inout) :: rdm
1277 type(namespace_t), intent(in) :: namespace
1278 type(hamiltonian_elec_t), intent(in) :: hm
1279 type(states_elec_t), intent(inout) :: st
1280 type(grid_t), intent(in) :: gr
1281 class(space_t), intent(in) :: space
1282
1283
1284 real(real64), allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1285 real(real64), allocatable :: v_ij(:,:,:,:,:)
1286 real(real64) :: dd
1287 type(states_elec_t) :: xst
1288
1289 integer :: ist, jst, nspin_, iorb, jorb, ip
1290
1292
1293
1294 nspin_ = min(st%d%nspin, 2)
1295
1296 if (.not. rdm%do_basis) then
1297 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1298 safe_allocate(rho1(1:gr%np))
1299 safe_allocate(rho(1:gr%np))
1300 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1301 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1302 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1303
1304 v_ij = m_zero
1305 rdm%eone = m_zero
1306 rdm%hartree = m_zero
1307 rdm%exchange = m_zero
1308
1309 !derivative of one-electron energy with respect to the natural orbitals occupation number
1310 do ist = 1, st%nst
1311 call states_elec_get_state(st, gr, ist, 1, dpsi)
1312
1313 ! calculate one-body energy
1314 call dhamiltonian_elec_apply_single(hm, namespace, gr, dpsi, hpsi, ist, 1, &
1316 rdm%eone(ist) = dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1317 end do
1318
1319 !integrals used for the hartree and exchange parts of the total energy and their derivatives
1320 ! maybe better to let that be done from the lower level routines like hamiltonian apply?
1322 ! only used to calculate total energy
1323 call xst%nullify()
1324 call dexchange_operator_compute_potentials(hm%exxop, namespace, space, gr, st, xst, hm%kpoints, f_out = v_ij)
1325 call states_elec_end(xst)
1326
1327 do ist = 1, st%nst
1328 call states_elec_get_state(st, gr, ist, 1, dpsi)
1329
1330 !$omp parallel do
1331 do ip = 1, gr%np
1332 rho1(ip) = dpsi(ip, 1)**2
1333 end do
1334 !$omp end parallel do
1335
1336 do jst = ist, st%nst
1337 rdm%hartree(ist, jst) = dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1338 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1339 call states_elec_get_state(st, gr, jst, 1, dpsi2)
1340 !$omp parallel do
1341 do ip = 1, gr%np
1342 rho(ip) = dpsi2(ip, 1)*dpsi(ip, 1)
1343 end do
1344 !$omp end parallel do
1345 rdm%exchange(ist, jst) = dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1346 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1347 end do
1348 end do
1349
1350
1351 safe_deallocate_a(hpsi)
1352 safe_deallocate_a(rho)
1353 safe_deallocate_a(rho1)
1354 safe_deallocate_a(dpsi)
1355 safe_deallocate_a(dpsi2)
1356 safe_deallocate_a(v_ij)
1357
1358 else !if energy derivatives are expanded in a basis set
1359
1360 do iorb = 1, st%nst
1361 rdm%eone(iorb) = m_zero
1362 do ist = 1, st%nst
1363 do jst = 1, st%nst
1364 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1365 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1366 end do
1367 end do
1368 end do
1369
1370 do iorb = 1, st%nst
1371 do jorb =1 , iorb
1372 rdm%hartree(iorb ,jorb) = m_zero
1373 rdm%exchange(iorb,jorb) = m_zero
1374 do ist =1, st%nst
1375 do jst =1, st%nst
1376 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1377 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1378 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1379 end do
1380 end do
1381 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1382 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1383 end do
1384 end do
1385 end if
1386
1387 pop_sub(rdm_derivatives)
1388 end subroutine rdm_derivatives
1389
1390 ! --------------------------------------------
1391 !calculates the one electron integrals in the basis of the initial orbitals
1392 subroutine rdm_integrals(rdm, namespace, hm, st, mesh)
1393 type(rdm_t), intent(inout) :: rdm
1394 type(namespace_t), intent(in) :: namespace
1395 type(hamiltonian_elec_t), intent(in) :: hm
1396 type(states_elec_t), intent(in) :: st
1397 class(mesh_t), intent(in) :: mesh
1398
1399 real(real64), allocatable :: hpsi(:, :)
1400 real(real64), allocatable :: dpsi(:, :), dpsi2(:, :)
1401 integer :: ist, jst
1402
1403 push_sub(rdm_integrals)
1404
1405 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1406 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1407 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1408
1409 !calculate integrals of the one-electron energy term with respect to the initial orbital basis
1410 do ist = 1, st%nst
1411 call states_elec_get_state(st, mesh, ist, 1, dpsi)
1412 do jst = ist, st%nst
1413 call states_elec_get_state(st, mesh, jst, 1, dpsi2)
1414
1415 ! calculate one-body integrals
1416 call dhamiltonian_elec_apply_single(hm, namespace, mesh, dpsi, hpsi, ist, 1, &
1418 rdm%eone_int(jst, ist) = dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1419 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1420 end do
1421 end do
1422
1423 safe_deallocate_a(hpsi)
1424 safe_deallocate_a(dpsi)
1425 safe_deallocate_a(dpsi2)
1426
1427 pop_sub(rdm_integrals)
1428 end subroutine rdm_integrals
1429
1430 ! --------------------------------------------
1431 ! constructs the Hartree and Exchange part of the RDMFT Fock matrix
1432 subroutine sum_integrals(rdm)
1433 type(rdm_t), intent(inout) :: rdm
1434
1435 integer :: ist, jst, kst, lst, iorb, icount
1436 logical :: inv_pairs
1437 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1438 real(real64), allocatable :: dm(:,:,:)
1439
1440 push_sub(sum_integrals)
1441
1442 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1443
1444 rdm%Coul = m_zero
1445 rdm%Exch = m_zero
1446 dm = m_zero
1447
1448 do iorb = 1, rdm%nst
1449 do ist = 1, rdm%nst
1450 do jst = 1, ist
1451 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1452 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1453 end do
1454 end do
1455 end do
1456
1457 do icount = 1, rdm%n_twoint
1458
1459 ist = rdm%i_index(1,icount)
1460 jst = rdm%j_index(1,icount)
1461 kst = rdm%k_index(1,icount)
1462 lst = rdm%l_index(1,icount)
1463
1464 two_int = rdm%twoint(icount)
1465
1466 ! create weights of unique integrals
1467 if(ist == jst) then
1468 wij = m_one
1469 else
1470 wij = m_two
1471 endif
1472 if(kst == lst) then
1473 wkl = m_one
1474 else
1475 wkl = m_two
1476 endif
1477
1478 if(ist == kst .and. jst /= lst) then
1479 wik = m_two
1480 else
1481 wik = m_one
1482 endif
1483 if(ist == lst .and. jst /= kst) then
1484 wil = m_two
1485 else
1486 wil = m_one
1487 endif
1488 if(jst == kst .and. ist /= lst) then
1489 wjk = m_two
1490 else
1491 wjk = m_one
1492 endif
1493 if(jst == lst .and. ist /= kst) then
1494 wjl = m_two
1495 else
1496 wjl = m_one
1497 endif
1498
1499 inv_pairs = (ist /= kst .or. jst /= lst)
1500
1501 do iorb = 1, rdm%nst
1502
1503 !the Hartree terms
1504 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1505 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1506
1507 !the exchange terms
1508 !weights are only included if they can differ from one
1509 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1510 if (kst /= lst) then
1511 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1512 end if
1513 if (ist /= jst) then
1514 if(jst >= kst) then
1515 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1516 else
1517 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1518 end if
1519 end if
1520 if (ist /=jst .and. kst /= lst) then
1521 if (jst >= lst) then
1522 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1523 else
1524 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1525 end if
1526 end if
1528 end do !iorb
1529 end do !icount
1530
1531 do iorb =1, rdm%nst
1532 do ist = 1, rdm%nst
1533 do jst = 1, ist-1
1534 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1535 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1536 end do
1537 end do
1538 end do
1539
1540 safe_deallocate_a(dm)
1541
1542 pop_sub(sum_integrals)
1543 end subroutine sum_integrals
1544
1545end module rdmft_oct_m
1546
1547
1548!! Local Variables:
1549!! mode: f90
1550!! coding: utf-8
1551!! End:
The same as above but with (Hermitian) transpose of A.
Definition: lalg_basic.F90:292
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
double sin(double __x) __attribute__((__nothrow__
double asin(double __x) __attribute__((__nothrow__
type(debug_t), save, public debug
Definition: debug.F90:156
This module implements a calculator for the density and defines related functions.
Definition: density.F90:122
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:653
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_partial(der, ff, op_ff, dir, ghost_update, set_bc)
apply the partial derivative along dir to a mesh function
subroutine, public deigensolver_cg(namespace, mesh, st, hm, pre, tol, niter, converged, ik, diff, energy_change_threshold, orthogonalize_to_all, conjugate_direction, shift)
conjugate-gradients method.
Definition: eigen_cg.F90:198
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
subroutine, public eigensolver_end(eigens)
subroutine, public dexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, F_out)
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
character(len= *), parameter, public static_dir
Definition: global.F90:280
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public grid_write_info(gr, iunit, namespace)
Definition: grid.F90:539
integer, parameter, public term_local_external
integer, parameter, public term_non_local_potential
integer, parameter, public term_kinetic
subroutine, public dhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
This module defines classes and functions for interaction partners.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
System information (time, memory, sysname)
Definition: loct.F90:117
subroutine, public loct_progress_bar(a, maxcount)
A wrapper around the progress bar, such that it can be silenced without needing to dress the call wit...
Definition: loct.F90:276
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
integer, parameter, public minmethod_bfgs
Definition: minimizer.F90:139
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
this module contains the low-level part of the output system
Definition: output_low.F90:117
subroutine, public output_modelmb(outp, namespace, space, dir, gr, ions, iter, st)
this module contains the output system
Definition: output.F90:117
subroutine, public output_all(outp, namespace, space, dir, gr, ions, iter, st, hm, ks)
Definition: output.F90:480
subroutine, public photon_mode_write_info(this, iunit, namespace)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
Definition: rdmft.F90:861
subroutine calc_maxfo(namespace, hm, st, gr, rdm)
Definition: rdmft.F90:694
subroutine objective_rdmft(size, theta, objective, getgrad, df)
Definition: rdmft.F90:1009
subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
Definition: rdmft.F90:1142
subroutine, public rdmft_end(rdm)
Definition: rdmft.F90:349
subroutine, public scf_rdmft(rdm, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
Definition: rdmft.F90:379
subroutine, public rdmft_init(rdm, namespace, gr, st, hm, mc, space, fromScratch)
Definition: rdmft.F90:215
subroutine write_iter_info_rdmft(iter, size, energy, maxdr, maxdf, theta)
Definition: rdmft.F90:1061
subroutine set_occ_pinning(st)
Definition: rdmft.F90:795
subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
Definition: rdmft.F90:729
subroutine assign_eigfunctions(rdm, st, lambda)
Definition: rdmft.F90:1292
subroutine construct_lambda(namespace, hm, st, gr, lambda, rdm)
Definition: rdmft.F90:1206
subroutine sum_integrals(rdm)
Definition: rdmft.F90:1528
subroutine rdm_integrals(rdm, namespace, hm, st, mesh)
Definition: rdmft.F90:1488
subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
Definition: rdmft.F90:1075
subroutine total_energy_rdm(rdm, occ, energy, dE_dn)
Definition: rdmft.F90:1322
subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
Definition: rdmft.F90:819
subroutine rdm_derivatives(rdm, namespace, hm, st, gr, space)
Definition: rdmft.F90:1371
pure logical function, public states_are_complex(st)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special, dest_type, copy_data)
make a (selective) copy of a states_elec_t object
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_dump(restart, space, st, mesh, kpoints, ierr, iter, lr, verbose)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
subroutine, public v_ks_write_info(ks, iunit, namespace)
Definition: v_ks.F90:631
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:720
This module provices a simple timer class which can be used to trigger the writing of a restart file ...
Definition: walltimer.F90:123
logical function, public restart_walltime_period_alarm(comm)
Definition: walltimer.F90:375
subroutine scf_write_static(dir, fname)
Definition: rdmft.F90:592
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Describes mesh distribution to nodes.
Definition: mesh.F90:187
Stores all communicators and groups.
Definition: multicomm.F90:208
output handler class
Definition: output_low.F90:166
The states_elec_t class contains all electronic wave functions.
int true(void)