Octopus
stress.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2016 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2023 N. Tancogne-Dejean
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
22! ---------------------------------------------------------
25module stress_oct_m
28 use comm_oct_m
29 use debug_oct_m
33 use energy_oct_m
35 use epot_oct_m
36 use global_oct_m
37 use grid_oct_m
39 use io_oct_m
41 use ions_oct_m
43 use, intrinsic :: iso_fortran_env
47 use lda_u_oct_m
50 use math_oct_m
51 use mesh_oct_m
55 use mpi_oct_m
60 use ps_oct_m
62 use space_oct_m
72 use types_oct_m
73 use unit_oct_m
75 use v_ks_oct_m
77 use xc_oct_m
78 use xc_f03_lib_m
80 implicit none
81
82 private
83 public :: &
87
88contains
89
90 ! ---------------------------------------------------------
92 subroutine stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
93 type(namespace_t), intent(in) :: namespace
94 type(grid_t), intent(inout) :: gr
95 type(hamiltonian_elec_t), intent(inout) :: hm
96 type(states_elec_t), target, intent(inout) :: st
97 type(ions_t), intent(inout) :: ions
98 type(v_ks_t), intent(in) :: ks
99 type(partner_list_t), intent(in) :: ext_partners
100
101 real(real64), allocatable :: rho_total(:)
102 real(real64) :: stress(3,3) ! stress tensor in Cartesian coordinate
103 real(real64) :: stress_kin(3,3), stress_Hartree(3,3), stress_xc(3,3), stress_xc_nlcc(3,3)
104 real(real64) :: stress_ps(3,3), stress_ps_nl(3,3), stress_ps_local(3,3), stress_ii(3,3)
105 real(real64) :: stress_hubbard(3,3)
106 integer :: ip
107 real(real64), allocatable :: vh(:)
108 real(real64), allocatable :: grad_vh(:,:)
109 real(real64) :: ehartree
110 real(real64), contiguous, pointer :: rho(:)
111
112 call profiling_in("STRESS_CALCULATE")
113 push_sub(stress_calculate)
114
115 if (st%wfs_type /= type_cmplx) then
116 write(message(1),'(a)') 'The stress tensors for real wavefunctions has not been implemented!'
117
118 if (hm%kpoints%full%npoints == 1) then
119 write(message(2),'(a)') 'For testing this feature, you can add ForceComplex=yes to the input file'
120 call messages_fatal(2, namespace=namespace)
121 end if
122
123 call messages_fatal(1, namespace=namespace)
124 end if
125
126 if (ions%space%periodic_dim == 1) then
127 call messages_not_implemented("Stress tensor for 1D periodic systems", namespace=namespace)
128 end if
129
130 if (.not. ions%space%is_periodic()) then
131 write(message(1),'(a)') 'The stress tensor cannot be computed for isolated systems'
132 call messages_fatal(1, namespace=namespace)
133 end if
134
135 if (ks%vdw%vdw_correction /= option__vdwcorrection__none .and. .not. any(ks%vdw%vdw_correction == d3_lib_options)) then
136 write(message(1),'(a)') 'The stress tensor is currently only implemented with DFT-D3 vdW correction'
137 call messages_fatal(1, namespace=namespace)
138 end if
139
140 if (hm%pcm%run_pcm) then
141 call messages_not_implemented('Stress tensor with PCM')
142 end if
143
144 if (allocated(hm%v_static)) then
145 call messages_not_implemented('Stress tensor with static electric fields')
146 end if
147
148 if (ks%has_photons) then
149 call messages_not_implemented('Stress tensor with photon modes')
150 end if
151
152 if (.not. hm%vnl%apply_projector_matrices) then
153 call messages_not_implemented('Stress tensor with relativistic Kleinman-Bylander pseudopotential')
154 end if
155
156 if (hm%ep%reltype == scalar_relativistic_zora .or. hm%ep%reltype == fully_relativistic_zora) then
157 call messages_not_implemented('Stress tensor with ZORA')
158 end if
159
160 ! Checks for the xc part of KS-DFT and GKS-DFT
161 if (ks%theory_level == kohn_sham_dft .or. ks%theory_level == generalized_kohn_sham_dft) then
162 if (.not. xc_is_energy_functional(hm%xc)) then
163 call messages_not_implemented("Stress tensor with xc functionals that are not energy functionals")
164 end if
165
166 if ( .not. in_family(hm%xc%family, [xc_family_lda, xc_family_gga])) then
167 write(message(1),'(a)') 'The stress tensor computation is currently only possible at the Kohn-Sham DFT level'
168 write(message(2),'(a)') 'with LDA and GGA functionals or for independent particles.'
169 call messages_fatal(2, namespace=namespace)
170 end if
171
172 if (in_family(hm%xc%family, [xc_family_gga]) .and. st%d%ispin == spinors) then
173 call messages_not_implemented("Stress tensor for GGAs with spinors", namespace=namespace)
174 end if
175 end if
176
177 if (hm%magnetic_constrain%level /= constrain_none) then
178 call messages_not_implemented("Stress tensor with MagneticConstrain /= constrain_none")
179 end if
180
181 stress(:,:) = m_zero
182
183 safe_allocate(rho_total(1:gr%np_part))
184 do ip = 1, gr%np
185 rho_total(ip) = sum(st%rho(ip, 1:st%d%nspin))
186 end do
187
188 ! As we rely on some of the full energy components, we need to recompute it first
189 ! TODO: We should restrict the components of the energy needed to be computed
190 call energy_calc_total(namespace, ions%space, hm, gr, st, ext_partners, iunit = -1, full = .true.)
191
192 ! In order to get the electrostatic part (Hartree and local pseudopotential part),
193 ! we need to get the Hartree potential and its gradient
194 safe_allocate(vh(1:gr%np_part))
195 safe_allocate(grad_vh(1:gr%np, 1:gr%der%dim))
196 if (ks%theory_level /= independent_particles) then
197 call lalg_copy(gr%np, hm%ks_pot%vhartree, vh)
198 else
199 if (hm%d%spin_channels > 1) then
200 safe_allocate(rho(1:gr%np_part))
201 call lalg_copy(gr%np, st%rho(:,1), rho)
202 call lalg_axpy(gr%np, m_one, st%rho(:,2), rho)
203 else
204 rho => st%rho(:,1)
205 end if
206 ! In the case of independent particles, we use the electron density without NLCC
207 call dpoisson_solve(hm%psolver, ions%namespace, vh, rho, all_nodes = .true.)
208 if (hm%d%spin_channels > 1) then
209 safe_deallocate_p(rho)
210 else
211 nullify(rho)
212 end if
213 end if
214 ehartree = hm%energy%hartree
215 ! We also compute the gradient here
216 call dderivatives_grad(gr%der, vh, grad_vh)
217
218 ! We now compute the various contributions to the stress tensor
219
220 ! Stress from kinetic energy of electrons
221 call stress_from_kinetic(gr, ions%space, hm, st, gr%symm, ions%latt%rcell_volume, stress_kin)
222 stress = stress + stress_kin
223
224 if (ks%theory_level == independent_particles) then
225 stress_hartree = m_zero
226 stress_xc = m_zero
227 stress_xc_nlcc = m_zero
228 else
229 call stress_from_hartree(gr, ions%space, ions%latt%rcell_volume, vh, grad_vh, ehartree, stress_hartree)
230 stress = stress + stress_hartree
231
232 call stress_from_xc(hm%energy, ions%latt%rcell_volume, ions%space%periodic_dim, stress_xc)
233
234 ! Nonlinear core correction contribution
235 if (allocated(st%rho_core)) then
236 call stress_from_xc_nlcc(ions%latt%rcell_volume, gr, st, ions, hm%ks_pot%vxc, stress_xc_nlcc)
237 else
238 stress_xc_nlcc = m_zero
239 end if
240 ! Adds the beyond LDA contribution to the stress tensor
241 stress_xc = stress_xc + ks%stress_xc_gga / ions%latt%rcell_volume
242 stress = stress + stress_xc + stress_xc_nlcc
243 end if
244
245 call stress_from_pseudo_local(gr, st, hm, ions, rho_total, vh, grad_vh, stress_ps_local)
246 stress_ps = stress_ps_local
247 stress = stress + stress_ps_local
248
249 safe_deallocate_a(vh)
250 safe_deallocate_a(grad_vh)
251
252 call stress_from_pseudo_nonloc(gr, st, hm, ions, stress_ps_nl)
253 stress_ps = stress_ps + stress_ps_nl
254 stress = stress + stress_ps_nl
255
256 call stress_from_hubbard(namespace, gr, st, hm, ions%space, ions%latt%rcell_volume, stress_hubbard)
257 stress = stress + stress_hubbard
258
259 call ion_interaction_stress(ions%ion_interaction, ions%space, ions%latt, ions%atom, ions%natoms, ions%pos, stress_ii)
260 stress = stress + stress_ii
261 ! Stress from kinetic energy of ion
262 ! Stress from ion-field interaction
263
264 ! Sign changed to fit conventional definition
265 stress = -stress
266 st%stress_tensors%kinetic = -stress_kin
267 st%stress_tensors%Hartree = -stress_hartree
268 st%stress_tensors%xc = -stress_xc
269 st%stress_tensors%xc_nlcc = -stress_xc_nlcc
270 st%stress_tensors%ps_local = -stress_ps_local
271 st%stress_tensors%ps_nl = -stress_ps_nl
272 st%stress_tensors%hubbard = -stress_hubbard
273 st%stress_tensors%ion_ion = -stress_ii
274
275 ! Stress contribution from vdW D3
276 if (ks%vdw%vdw_correction /= option__vdwcorrection__none) then
277 st%stress_tensors%vdw = hm%ep%vdw_stress
278 else
279 st%stress_tensors%vdw = m_zero
280 end if
281 stress = stress + st%stress_tensors%vdw
282
283 ! Symmetrize the stress tensor if we use k-point symmetries
284 if (hm%kpoints%use_symmetries) then
285 call dsymmetrize_tensor_cart(gr%symm, stress, use_non_symmorphic=.true.)
286 end if
287 ! We guarantee that the matrix is truely symmetric. There could be small numerical assymetries after symmetrization
288 call dsymmetrize_matrix(ions%space%periodic_dim, stress)
289
290 st%stress_tensors%total = stress
291
292 ! Some sumrule for validation
293 ! Sumrule is -3P_{kin}\Omega = 2 E_{kin}
294 st%stress_tensors%kinetic_sumrule = m_zero
295 ! Sumrule is -3P_{Hartree}\Omega = E_{Hartree}
296 st%stress_tensors%Hartree_sumrule = m_zero
297 if(ions%space%periodic_dim == 3) then
298 st%stress_tensors%kinetic_sumrule = (stress_kin(1,1) + stress_kin(2,2) + stress_kin(3,3))*ions%latt%rcell_volume
299 st%stress_tensors%kinetic_sumrule = st%stress_tensors%kinetic_sumrule - m_two * hm%energy%kinetic
300
301 st%stress_tensors%hartree_sumrule = (stress_hartree(1,1) + stress_hartree(2,2) + stress_hartree(3,3))*ions%latt%rcell_volume
302 st%stress_tensors%hartree_sumrule = st%stress_tensors%hartree_sumrule - hm%energy%hartree
303 end if
304
305 safe_deallocate_a(rho_total)
306
307 pop_sub(stress_calculate)
308 call profiling_out("STRESS_CALCULATE")
309 end subroutine stress_calculate
310
311 ! -------------------------------------------------------
326 subroutine stress_from_kinetic(gr, space, hm, st, symm, rcell_volume, stress_kin)
327 type(grid_t), intent(in) :: gr
328 class(space_t), intent(in) :: space
329 type(hamiltonian_elec_t), intent(in) :: hm
330 type(states_elec_t), intent(in) :: st
331 type(symmetries_t), intent(in) :: symm
332 real(real64), intent(in) :: rcell_volume
333 real(real64), intent(out) :: stress_kin(3, 3)
334
335 integer :: ik, ist, idir, jdir, ib, minst, maxst
336 complex(real64), allocatable :: stress_l_block(:)
337 type(wfs_elec_t) :: psib, gpsib(space%dim)
338
339 call profiling_in("STRESS_FROM_KINETIC")
340 push_sub(stress_from_kinetic)
341
342 stress_kin(:,:) = m_zero
343
344 safe_allocate(stress_l_block(1:st%block_size))
345
346 do ik = st%d%kpt%start, st%d%kpt%end
347 if (st%kweights(ik) <= m_epsilon) cycle
348
349 do ib = st%group%block_start, st%group%block_end
350 minst = states_elec_block_min(st, ib)
351 maxst = states_elec_block_max(st, ib)
352
353 call hamiltonian_elec_copy_and_set_phase(hm, gr, st%d%kpt, st%group%psib(ib, ik), psib)
354
355 ! calculate the gradient
356 call zderivatives_batch_grad(gr%der, psib, gpsib, set_bc=.false.)
357
358 ! Accumulate the result
359 do idir = 1, space%periodic_dim
360 do jdir = idir, space%periodic_dim
361 call zmesh_batch_dotp_vector(gr, gpsib(idir), gpsib(jdir), stress_l_block)
362
363 do ist = minst, maxst
364 stress_kin(idir,jdir) = stress_kin(idir,jdir) &
365 + st%kweights(ik) * st%occ(ist, ik) &
366 * real(stress_l_block(ist - minst + 1), real64)
367 end do
368 end do
369 end do
370
371 do idir = 1, space%dim
372 call gpsib(idir)%end()
373 end do
374 call psib%end()
375
376 end do
377 end do
378
379 if (st%parallel_in_states .or. st%d%kpt%parallel) then
380 call comm_allreduce(st%st_kpt_mpi_grp, stress_kin)
381 end if
382
383
384 ! Symmetrize the kinetic stress tensor
385 call upper_triangular_to_hermitian(space%periodic_dim, stress_kin)
386
387 ! Symmetrize the stress tensor if we use k-point symmetries
388 if (hm%kpoints%use_symmetries) then
389 call dsymmetrize_tensor_cart(symm, stress_kin, use_non_symmorphic=.true.)
390 end if
391
392 stress_kin = stress_kin / rcell_volume
393
394 call profiling_out("STRESS_FROM_KINETIC")
395 pop_sub(stress_from_kinetic)
396 end subroutine stress_from_kinetic
397
398 ! -------------------------------------------------------
415 subroutine stress_from_hartree(gr, space, volume, vh, grad_vh, ehartree, stress_Hartree)
416 type(grid_t), intent(in) :: gr
417 class(space_t), intent(in) :: space
418 real(real64), intent(in) :: volume
419 real(real64), intent(in) :: vh(:)
420 real(real64), intent(in) :: grad_vh(:,:)
421 real(real64), intent(in) :: ehartree
422 real(real64), intent(out) :: stress_Hartree(3, 3)
423
424 integer :: idir, jdir
425
426 call profiling_in("STRESS_FROM_HARTREE")
427 push_sub(stress_from_hartree)
428
429 stress_hartree(:,:) = m_zero
430
431 do idir = 1, space%periodic_dim
432 do jdir = idir, space%periodic_dim
433 stress_hartree(idir, jdir) = -dmf_dotp(gr, grad_vh(:,idir), grad_vh(:, jdir))/m_four/m_pi
434 end do
435 stress_hartree(idir, idir) = stress_hartree(idir, idir) + ehartree
436 end do
437
438 call upper_triangular_to_hermitian(space%periodic_dim, stress_hartree)
439
440 stress_hartree = stress_hartree/volume
441
442 call profiling_out("STRESS_FROM_HARTREE")
443 pop_sub(stress_from_hartree)
444 end subroutine stress_from_hartree
445
446
447 ! -------------------------------------------------------
461 !
462 ! Note: We assume hm%energy%echange, correlation, and intnvxc
463 ! have already been calculated somewhere else.
464 subroutine stress_from_xc(energy, rcell_volume, periodic_dim, stress_xc)
465 type(energy_t), intent(in) :: energy
466 real(real64), intent(in) :: rcell_volume
467 integer, intent(in) :: periodic_dim
468 real(real64), intent(out) :: stress_xc(3, 3)
469
470 integer :: idir
471
472 call profiling_in("STRESS_FROM_XC")
473 push_sub(stress_from_xc)
474
475 stress_xc = m_zero
476 do idir = 1, periodic_dim
477 stress_xc(idir, idir) = - energy%exchange - energy%correlation + energy%intnvxc
478 end do
479 stress_xc(:,:) = stress_xc(:,:) / rcell_volume
480
481 call profiling_out("STRESS_FROM_XC")
482 pop_sub(stress_from_xc)
483 end subroutine stress_from_xc
484
485
486 ! -------------------------------------------------------
495 subroutine stress_from_xc_nlcc(rcell_volume, gr, st, ions, vxc, stress_xc_nlcc)
496 real(real64), intent(in) :: rcell_volume
497 type(grid_t), intent(in) :: gr
498 type(states_elec_t), intent(in) :: st
499 type(ions_t), intent(in) :: ions
500 real(real64), intent(in) :: vxc(:,:)
501 real(real64), intent(out) :: stress_xc_nlcc(3, 3)
502
503 integer :: idir, jdir, iat, ip
504 real(real64), allocatable :: nlcc(:), gvxc(:,:), nlcc_x(:,:), vxc_tot(:)
505
506 call profiling_in("STRESS_FROM_XC_NLCC")
507 push_sub(stress_from_xc_nlcc)
509 assert(allocated(st%rho_core))
510
511 stress_xc_nlcc = m_zero
512
513 safe_allocate(vxc_tot(1:gr%np_part))
514 safe_allocate(nlcc(1:gr%np))
515 safe_allocate(nlcc_x(1:gr%np, 1:gr%der%dim))
516
517 ! Sum over spin of the xc potential
518 call lalg_copy(gr%np, vxc(:, 1), vxc_tot)
519 if(st%d%nspin > 1) call lalg_axpy(gr%np, m_one, vxc(:, 2), vxc_tot)
520
521 ! We first accumulate the contribution from all the pseudo-ions
522 ! Here nlcc_x corresponds to
523 ! \sum_I \rho_{NLCC}^I(r-R_I) (r-R_I)
524 nlcc_x = m_zero
525 do iat = ions%atoms_dist%start, ions%atoms_dist%end
526 call species_get_nlcc(ions%atom(iat)%species, ions%space, ions%latt, &
527 ions%pos(:,iat), gr, nlcc)
528
529 do idir = 1, ions%space%periodic_dim
530 !$omp parallel do
531 do ip = 1, gr%np
532 nlcc_x(ip, idir) = nlcc_x(ip, idir) + (gr%x(ip, idir) - ions%pos(idir,iat)) * nlcc(ip)
533 end do
534 stress_xc_nlcc(idir, idir) = stress_xc_nlcc(idir, idir) + dmf_dotp(gr, nlcc, vxc_tot)
535 end do
536 end do
537 safe_deallocate_a(nlcc)
538
539 if (ions%atoms_dist%parallel) then
540 call comm_allreduce(ions%atoms_dist%mpi_grp, nlcc_x)
541 call comm_allreduce(ions%atoms_dist%mpi_grp, stress_xc_nlcc)
542 end if
543
544 safe_allocate(gvxc(1:gr%np, 1:gr%der%dim))
545 call dderivatives_grad(gr%der, vxc_tot, gvxc)
546
547 do idir = 1, ions%space%periodic_dim
548 do jdir = idir, ions%space%periodic_dim
549 stress_xc_nlcc(idir, jdir) = stress_xc_nlcc(idir, jdir) + dmf_dotp(gr, gvxc(:,idir), nlcc_x(:,jdir))
550 end do
551 end do
552 safe_deallocate_a(vxc_tot)
553 safe_deallocate_a(gvxc)
554 safe_deallocate_a(nlcc_x)
555
556 call upper_triangular_to_hermitian(ions%space%periodic_dim, stress_xc_nlcc)
558 stress_xc_nlcc(:,:) = stress_xc_nlcc(:,:) / rcell_volume
559
560 call profiling_out("STRESS_FROM_XC_NLCC")
561 pop_sub(stress_from_xc_nlcc)
562 end subroutine stress_from_xc_nlcc
563
564 ! -------------------------------------------------------
583 subroutine stress_from_pseudo_nonloc(gr, st, hm, ions, stress_ps_nl)
584 type(grid_t), target, intent(in) :: gr
585 type(states_elec_t), intent(inout) :: st
586 type(hamiltonian_elec_t), intent(in) :: hm
587 type(ions_t), intent(in) :: ions
588 real(real64), intent(out) :: stress_ps_nl(3, 3)
589
590 integer :: ik, ist, idir, jdir
591 integer :: ib, minst, maxst
592 type(wfs_elec_t) :: psib, rvnl_psib(3), gpsib(3)
593 complex(real64), allocatable :: stress_tmp(:)
594
595 call profiling_in("STRESS_FROM_PSEUDO_NL")
597
598 assert(st%wfs_type == type_cmplx)
599
600 safe_allocate(stress_tmp(1:st%block_size))
601
602 stress_ps_nl = m_zero
603
604 do ik = st%d%kpt%start, st%d%kpt%end
605
606 if (st%kweights(ik) <= m_epsilon) cycle
607
608 do ib = st%group%block_start, st%group%block_end
609 minst = states_elec_block_min(st, ib)
610 maxst = states_elec_block_max(st, ib)
611
612 call hamiltonian_elec_copy_and_set_phase(hm, gr, st%d%kpt, st%group%psib(ib, ik), psib)
613
614 ! calculate the gradient
615 call zderivatives_batch_grad(gr%der, psib, gpsib, set_bc=.false.)
616
617
618 ! Get rV_NL |\psi> for all atoms
619 do idir = 1, gr%der%dim
620 call psib%copy_to(rvnl_psib(idir))
621 call batch_set_zero(rvnl_psib(idir))
622 end do
623 call hm%vnl%zr_vn_local(gr, st%d, gr%der%boundaries%spiral, psib, rvnl_psib)
624
625 do idir = 1, ions%space%periodic_dim
626 do jdir = idir, ions%space%periodic_dim
627 call zmesh_batch_dotp_vector(gr, gpsib(idir), rvnl_psib(jdir), stress_tmp)
628
629 do ist = minst, maxst
630 stress_ps_nl(idir, jdir) = stress_ps_nl(idir, jdir) &
631 + m_two * st%kweights(ik) * st%occ(ist, ik) * real(stress_tmp(ist-minst+1), real64)
632 end do
633
634 end do
635 end do
636
637 do idir = 1, gr%der%dim
638 call rvnl_psib(idir)%end()
639 call gpsib(idir)%end()
640 end do
641 call psib%end()
642 end do
643 end do
644
645 safe_deallocate_a(stress_tmp)
646
647 if (st%parallel_in_states .or. st%d%kpt%parallel) then
648 call comm_allreduce(st%st_kpt_mpi_grp, stress_ps_nl)
649 end if
650
651 ! Symmetrize the kinetic stress tensor
652 call upper_triangular_to_hermitian(ions%space%periodic_dim, stress_ps_nl)
653
654 ! Symmetrize the stress tensor if we use k-point symmetries
655 if (hm%kpoints%use_symmetries) then
656 call dsymmetrize_tensor_cart(gr%symm, stress_ps_nl, use_non_symmorphic=.true.)
657 end if
658
659 ! Add the nonlocal energy
660 do idir = 1, ions%space%periodic_dim
661 stress_ps_nl(idir, idir) = stress_ps_nl(idir, idir) + hm%energy%extern_non_local
662 end do
663
664 stress_ps_nl = stress_ps_nl/ions%latt%rcell_volume
665
666 call profiling_out("STRESS_FROM_PSEUDO_NL")
668
669 end subroutine stress_from_pseudo_nonloc
670
671
672 ! -------------------------------------------------------
689 subroutine stress_from_pseudo_local(gr, st, hm, ions, rho_total, vh, grad_vh, stress_ps_local)
690 type(grid_t), target, intent(in) :: gr
691 type(states_elec_t), intent(inout) :: st
692 type(hamiltonian_elec_t), intent(in) :: hm
693 type(ions_t), intent(in) :: ions
694 real(real64), contiguous, intent(inout) :: rho_total(:)
695 real(real64), intent(in) :: vh(:)
696 real(real64), intent(in) :: grad_vh(:,:)
697 real(real64), intent(out) :: stress_ps_local(3, 3)
698
699
700 real(real64) :: stress_SR(3, 3), stress_LR(3, 3)
701 real(real64) :: energy_ps_SR, charge, zi
702 real(real64), allocatable :: vloc(:), rvloc(:,:), rho_local_lr(:), rho_lr(:)
703 real(real64), allocatable :: grad_rho(:,:), rho_lr_x(:,:), vlr(:), grad_vlr(:,:)
704 integer :: idir, jdir, iatom
705 type(ps_t), pointer :: spec_ps
706
707 call profiling_in("STRESS_FROM_PSEUDO_LOC")
709
710 ! calculate stress from short-range local pseudopotentials
711 stress_sr = m_zero
712
713 safe_allocate(vloc(1:gr%np))
714 vloc = m_zero
715 safe_allocate(rvloc(1:gr%np, 1:gr%der%dim))
716 rvloc = m_zero
717 do iatom = 1, ions%natoms
718 call epot_local_pseudopotential_sr(gr, ions, iatom, vloc, rvloc)
719 end do
720 safe_deallocate_a(vloc)
721
722 safe_allocate(grad_rho(1:gr%np,1:gr%der%dim))
723 call dderivatives_grad(gr%der, rho_total, grad_rho)
724
725 energy_ps_sr = hm%energy%extern_local
726 do idir = 1, ions%space%periodic_dim
727 do jdir = idir, ions%space%periodic_dim
728 stress_sr(idir, jdir) = stress_sr(idir, jdir) &
729 +dmf_dotp(gr, rvloc(:, jdir), grad_rho(:, idir))
730 end do
731 stress_sr(idir,idir) = stress_sr(idir,idir) + energy_ps_sr
732 end do
733
734 call upper_triangular_to_hermitian(ions%space%periodic_dim, stress_sr)
735
736 stress_sr = stress_sr/ions%latt%rcell_volume
737
738 safe_deallocate_a(rvloc)
739 safe_deallocate_a(grad_rho)
740
741
742 ! calculate stress from long-range local pseudopotentials
743 stress_lr = m_zero
744
745 ! We treat the long-range part of the local potential as the Hartree term
746 ! We first sum the long range densities from atoms
747 safe_allocate(rho_lr(1:gr%np_part))
748 safe_allocate(rho_lr_x(1:gr%np, 1:gr%der%dim))
749 rho_lr = m_zero
750 rho_lr_x = m_zero
751 safe_allocate(rho_local_lr(1:gr%np))
752 do iatom = ions%atoms_dist%start, ions%atoms_dist%end
753 assert(ions%atom(iatom)%species%is_ps())
754 call species_get_long_range_density(ions%atom(iatom)%species, ions%namespace, ions%space, ions%latt, &
755 ions%pos(:, iatom), gr, rho_local_lr, nlr_x=rho_lr_x)
756
757 call lalg_axpy(gr%np, m_one, rho_local_lr, rho_lr)
758 end do
759 safe_deallocate_a(rho_local_lr)
760
761 if (ions%atoms_dist%parallel) then
762 call comm_allreduce(ions%atoms_dist%mpi_grp, rho_lr)
763 call comm_allreduce(ions%atoms_dist%mpi_grp, rho_lr_x)
764 end if
765
766 do idir = 1, ions%space%periodic_dim
767 do jdir = idir, ions%space%periodic_dim
768 stress_lr(idir, jdir) = stress_lr(idir, jdir) + dmf_dotp(gr, rho_lr_x(:,jdir), grad_vh(:, idir))
769 end do
770 end do
771 safe_deallocate_a(rho_lr_x)
772
773 safe_allocate(vlr(1:gr%np_part))
774 call dpoisson_solve(hm%psolver, ions%namespace, vlr, rho_lr, all_nodes = .true.)
775 safe_deallocate_a(rho_lr)
776
777 safe_allocate(grad_vlr(1:gr%np, 1:gr%der%dim))
778 call dderivatives_grad(gr%der, vlr, grad_vlr)
779 safe_deallocate_a(vlr)
780
781 do idir = 1, ions%space%periodic_dim
782 do jdir = idir, ions%space%periodic_dim
783 stress_lr(idir, jdir) = stress_lr(idir, jdir) - dmf_dotp(gr, grad_vh(:,idir), grad_vlr(:, jdir))/m_two/m_pi
784 end do
785 end do
786
787 call upper_triangular_to_hermitian(ions%space%periodic_dim, stress_lr)
788
789 safe_deallocate_a(grad_vlr)
790
791 ! Contribution from G=0 component of the long-range part
792 !
793 if (ions%space%periodic_dim == 3) then
794 charge = m_zero
795 do iatom = 1, ions%natoms
796 charge = charge + ions%atom(iatom)%species%get_zval()
797 end do
798
799 do iatom = 1, ions%natoms
800 select type(spec => ions%atom(iatom)%species)
801 type is(pseudopotential_t)
802 zi = spec%get_zval()
803 spec_ps => spec%ps
804
805 do idir = 1, ions%space%periodic_dim
806 stress_lr(idir, idir) = stress_lr(idir, idir) &
807 + m_two*m_pi*spec_ps%sigma_erf**2*charge*zi /ions%latt%rcell_volume
808 end do
809 end select
810 end do
811 end if
812
813 stress_lr = stress_lr/ions%latt%rcell_volume
814
815 stress_ps_local = stress_sr + stress_lr
816
817 call profiling_out("STRESS_FROM_PSEUDO_LOC")
819
820 end subroutine stress_from_pseudo_local
821
822 ! -------------------------------------------------------
823 subroutine epot_local_pseudopotential_sr(mesh, ions, iatom, vpsl, rvpsl)
824 class(mesh_t), intent(in) :: mesh
825 type(ions_t), intent(in) :: ions
826 integer, intent(in) :: iatom
827 real(real64), intent(inout) :: vpsl(:)
828 real(real64), intent(inout) :: rvpsl(:,:)
829
830 integer :: ip
831 real(real64) :: radius, vl_ip
832 type(submesh_t) :: sphere
833 type(ps_t), pointer :: ps
834
836
837 if (.not. ions%atom(iatom)%species%is_ps()) then
839 return
840 endif
841
842 call profiling_in("EPOT_LOCAL_PS_SR")
843
844 select type(spec=>ions%atom(iatom)%species)
845 type is(pseudopotential_t)
846
847 ps => spec%ps
848
849 radius = ps%vl%x_threshold*1.05_real64
850
851 call submesh_init(sphere, ions%space, mesh, ions%latt, ions%pos(:, iatom), radius)
852
853 ! Cannot be written (correctly) as a vector expression since for periodic systems,
854 ! there can be values ip, jp such that sphere%map(ip) == sphere%map(jp).
855 do ip = 1, sphere%np
856 vl_ip = spline_eval(ps%vl, sphere%r(ip))
857 vpsl(sphere%map(ip)) = vpsl(sphere%map(ip)) + vl_ip
858 rvpsl(sphere%map(ip), 1:ions%space%periodic_dim) = rvpsl(sphere%map(ip), 1:ions%space%periodic_dim) &
859 + sphere%rel_x(1:ions%space%periodic_dim, ip) * vl_ip
860 end do
861
862 call submesh_end(sphere)
863
864 nullify(ps)
865
866 end select
867
868 call profiling_out("EPOT_LOCAL_PS_SR")
870 end subroutine epot_local_pseudopotential_sr
871
872
873 ! -------------------------------------------------------
887 subroutine stress_from_hubbard(namespace, gr, st, hm, space, rcell_volume, stress_hubbard)
888 type(namespace_t), intent(in) :: namespace
889 type(grid_t), target, intent(in) :: gr
890 type(states_elec_t), intent(in) :: st
891 type(hamiltonian_elec_t), intent(in) :: hm
892 type(space_t), intent(in) :: space
893 real(real64), intent(in) :: rcell_volume
894 real(real64), intent(out) :: stress_hubbard(3, 3)
895
896 integer :: ik, ist, idir, jdir
897 integer :: ib, minst, maxst
898 type(wfs_elec_t) :: psib, rvu_psib(3), gpsib(3)
899 complex(real64), allocatable :: stress_tmp(:)
900
901 if (hm%lda_u%level == dft_u_none) then
902 stress_hubbard = m_zero
903 return
904 end if
905
906 push_sub_with_profile(stress_from_hubbard)
907
908 assert(st%wfs_type == type_cmplx)
909
910 safe_allocate(stress_tmp(1:st%block_size))
911
912 stress_hubbard = m_zero
913
914 do ik = st%d%kpt%start, st%d%kpt%end
915
916 if (st%kweights(ik) <= m_epsilon) cycle
917
918 do ib = st%group%block_start, st%group%block_end
919 minst = states_elec_block_min(st, ib)
920 maxst = states_elec_block_max(st, ib)
921
922 call hamiltonian_elec_copy_and_set_phase(hm, gr, st%d%kpt, st%group%psib(ib, ik), psib)
923
924 ! calculate the gradient
925 call zderivatives_batch_grad(gr%der, psib, gpsib, set_bc=.false.)
926
927 ! Get rV_U |\psi> for all atoms
928 do idir = 1, gr%der%dim
929 call psib%copy_to(rvu_psib(idir))
930 call batch_set_zero(rvu_psib(idir))
931 end do
932
933 call zlda_u_rvu(hm%lda_u, gr, space, hm%d, namespace, psib, rvu_psib)
934
935 do idir = 1,3
936 do jdir = idir,3
937 call zmesh_batch_dotp_vector(gr, gpsib(idir), rvu_psib(jdir), stress_tmp)
938
939 do ist = minst, maxst
940 stress_hubbard(idir, jdir) = stress_hubbard(idir, jdir) &
941 + m_two * st%kweights(ik) * st%occ(ist, ik) * real(stress_tmp(ist-minst+1), real64)
942 end do
943
944 end do
945 end do
946
947 do idir = 1, gr%der%dim
948 call rvu_psib(idir)%end()
949 call gpsib(idir)%end()
950 end do
951 call psib%end()
952 end do
953 end do
954
955 safe_deallocate_a(stress_tmp)
956
957 if (st%parallel_in_states .or. st%d%kpt%parallel) then
958 call comm_allreduce(st%st_kpt_mpi_grp, stress_hubbard)
959 end if
960
961 ! Symmetrize the kinetic stress tensor
962 call upper_triangular_to_hermitian(gr%der%dim, stress_hubbard)
963
964 ! Symmetrize the stress tensor if we use k-point symmetries
965 if (hm%kpoints%use_symmetries) then
966 call dsymmetrize_tensor_cart(gr%symm, stress_hubbard)
967 end if
968
969 ! Add the Hubbard energy
970 do idir = 1,3
971 stress_hubbard(idir, idir) = stress_hubbard(idir, idir) + hm%energy%int_dft_u
972 end do
973
974 stress_hubbard = stress_hubbard/rcell_volume
975
976 pop_sub_with_profile(stress_from_hubbard)
977 end subroutine stress_from_hubbard
978
979
980 ! -------------------------------------------------------
981 subroutine output_stress(iunit, space_dim, stress_tensors, all_terms)
982 integer, intent(in) :: iunit
983 integer, intent(in) :: space_dim
984 type(stress_t), intent(in) :: stress_tensors
985 logical, optional, intent(in) :: all_terms
986
987 logical :: write_all_terms
988 character(len=16) :: stress_unit
989
990 write_all_terms = optional_default(all_terms, .true.)
991
992 write(stress_unit, '(4a,i1)') trim(units_abbrev(units_out%energy)), '/', &
993 trim(units_abbrev(units_out%length)), '^', space_dim
994
995 if (mpi_grp_is_root(mpi_world)) then
996
997 if (write_all_terms) then
998 write(iunit, '(3a)') 'Kinetic stress tensor [', trim(stress_unit), '] ='
999 call print_stress_tensor(iunit, space_dim, stress_tensors%kinetic)
1000 if (space_dim == 3) then
1001 write(iunit, '(a, es15.6, 3a)') 'Kinetic pressure sumrule violation: ', &
1002 units_from_atomic(units_out%energy, stress_tensors%kinetic_sumrule), &
1003 ' [', trim(units_abbrev(units_out%energy)), ']'
1004 write(iunit,*)
1005 end if
1006
1007
1008 write(iunit, '(3a)') 'Hartree stress tensor [', trim(stress_unit), '] ='
1009 call print_stress_tensor(iunit, space_dim, stress_tensors%Hartree)
1010 if (space_dim == 3) then
1011 write(iunit, '(a, es15.6, 3a)') 'Hartree pressure sumrule violation: ', &
1012 units_from_atomic(units_out%energy, stress_tensors%hartree_sumrule), &
1013 ' [', trim(units_abbrev(units_out%energy)), ']'
1014 write(iunit,*)
1015 end if
1016
1017 write(iunit, '(3a)') 'XC stress tensor [', trim(stress_unit), '] ='
1018 call print_stress_tensor(iunit, space_dim, stress_tensors%xc)
1019
1020 write(iunit, '(3a)') 'XC NLCC stress tensor [', trim(stress_unit), '] ='
1021 call print_stress_tensor(iunit, space_dim, stress_tensors%xc_nlcc)
1022
1023 write(iunit, '(3a)') 'Local pseudo. stress tensor [', trim(stress_unit), '] ='
1024 call print_stress_tensor(iunit, space_dim, stress_tensors%ps_local)
1025
1026 write(iunit, '(3a)') 'Nonlocal pseudo. stress tensor [', trim(stress_unit), '] ='
1027 call print_stress_tensor(iunit, space_dim, stress_tensors%ps_nl)
1028
1029 write(iunit, '(3a)') 'Ion-ion stress tensor [', trim(stress_unit), '] ='
1030 call print_stress_tensor(iunit, space_dim, stress_tensors%ion_ion)
1031
1032 write(iunit, '(3a)') 'vdW stress tensor [', trim(stress_unit), '] ='
1033 call print_stress_tensor(iunit, space_dim, stress_tensors%vdw)
1034
1035 write(iunit, '(3a)') 'Hubbard stress tensor [', trim(stress_unit), '] ='
1036 call print_stress_tensor(iunit, space_dim, stress_tensors%hubbard)
1037 end if
1038
1039 write(iunit, '(3a)') 'Total stress tensor [', trim(stress_unit), '] ='
1040 call print_stress_tensor(iunit, space_dim, stress_tensors%total)
1041
1042 end if
1043 end subroutine output_stress
1044
1045
1046 subroutine output_pressure(iunit, space_dim, total_stress_tensor)
1047 integer, intent(in) :: iunit
1048 integer, intent(in) :: space_dim
1049 real(real64), intent(in) :: total_stress_tensor(3,3)
1050
1051 integer :: idim
1052 real(real64) :: pressure
1053 character(len=16) :: stress_unit
1054
1055 write(stress_unit, '(4a,i1)') trim(units_abbrev(units_out%energy)), '/', &
1056 trim(units_abbrev(units_out%length)), '^', space_dim
1057
1058 pressure = m_zero
1059 do idim = 1, space_dim
1060 pressure = pressure - total_stress_tensor(idim, idim) / real(space_dim, real64)
1061 end do
1062
1063 write(iunit,'(3a,es16.8)', advance="no") 'Pressure [', trim(stress_unit), '] = ', &
1064 units_from_atomic(units_out%energy/units_out%length**space_dim, pressure)
1065 if (space_dim == 3) then
1066 write(iunit,'(2x,a,f16.8)') 'Pressure [GPa] = ', units_from_atomic(unit_gpa, pressure)
1067 else
1068 write(iunit,*)
1069 end if
1070
1071 end subroutine output_pressure
1072
1073 subroutine print_stress_tensor(ounit, space_dim, tensor)
1074 integer, intent(in) :: ounit
1075 integer, intent(in) :: space_dim
1076 real(real64), intent(in) :: tensor(3,3)
1077
1078 real(real64) :: tensor_with_unit(3,3)
1079 integer :: idim, jdim
1080
1081 tensor_with_unit = units_from_atomic(units_out%energy/units_out%length**space_dim, tensor)
1082
1083 write(ounit,'(a9,2x)', advance="no")"T_{ij}"
1084 do jdim = 1, space_dim
1085 write(ounit,'(i18)', advance="no") jdim
1086 end do
1087 write(ounit,*)
1088 do idim = 1, space_dim
1089 write(ounit,'(i9,2x)', advance="no") idim
1090 do jdim = 1, space_dim
1091 write(ounit,'(es18.9)', advance="no") tensor_with_unit(idim, jdim)
1092 end do
1093 write(ounit,*)
1094 end do
1095 write(ounit,*)
1096
1097 end subroutine print_stress_tensor
1098
1099
1100end module stress_oct_m
1101
1102!! Local Variables:
1103!! mode: f90
1104!! coding: utf-8
1105!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:171
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:186
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
subroutine, public batch_set_zero(this, np, async)
fill all mesh functions of the batch with zero
Definition: batch_ops.F90:242
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:122
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
subroutine, public zderivatives_batch_grad(der, ffb, opffb, ghost_update, set_bc, to_cartesian, metric, factor)
apply the gradient to a batch of mesh functions
integer, parameter, public spinors
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,...
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:166
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:166
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
real(real64), parameter, public m_four
Definition: global.F90:192
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:186
real(real64), parameter, public m_epsilon
Definition: global.F90:204
real(real64), parameter, public m_one
Definition: global.F90:189
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
Copy a batch to another batch and apply the Bloch phase to it.
This module defines classes and functions for interaction partners.
Definition: io.F90:114
subroutine, public ion_interaction_stress(this, space, latt, atom, natoms, pos, stress_ii)
Computes the contribution to the stress tensor the ion-ion energy.
A module to handle KS potential, without the external potential.
integer, parameter, public independent_particles
integer, parameter, public generalized_kohn_sham_dft
integer, parameter, public kohn_sham_dft
integer, parameter, public dft_u_none
Definition: lda_u.F90:201
subroutine, public zlda_u_rvu(this, mesh, space, d, namespace, psib, gpsib)
This routine computes .
Definition: lda_u.F90:5304
This modules implements the routines for doing constrain DFT for noncollinear magnetism.
integer, parameter, public constrain_none
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public dsymmetrize_matrix(nn, aa)
Definition: math.F90:1456
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:116
subroutine, public zmesh_batch_dotp_vector(mesh, aa, bb, dot, reduce, cproduct)
calculate the vector of dot-products of mesh functions between two batches
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1114
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:161
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:415
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
Definition: mpi.F90:430
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:892
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
Definition: ps.F90:114
subroutine, public species_get_long_range_density(species, namespace, space, latt, pos, mesh, rho, sphere_inout, nlr_x)
subroutine, public species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
real(real64) function, public spline_eval(spl, x)
Definition: splines.F90:441
This module handles spin dimensions of the states and the k-point distribution.
integer pure function, public states_elec_block_max(st, ib)
return index of last state in block ib
integer pure function, public states_elec_block_min(st, ib)
return index of first state in block ib
This module implements the calculation of the stress tensor.
Definition: stress.F90:118
subroutine stress_from_kinetic(gr, space, hm, st, symm, rcell_volume, stress_kin)
Computes the contribution to the stress tensor from the kinetic energy.
Definition: stress.F90:420
subroutine stress_from_xc(energy, rcell_volume, periodic_dim, stress_xc)
Computes the contribution to the stress tensor from the xc energy.
Definition: stress.F90:558
subroutine print_stress_tensor(ounit, space_dim, tensor)
Definition: stress.F90:1167
subroutine, public output_pressure(iunit, space_dim, total_stress_tensor)
Definition: stress.F90:1140
subroutine epot_local_pseudopotential_sr(mesh, ions, iatom, vpsl, rvpsl)
Definition: stress.F90:917
subroutine, public stress_calculate(namespace, gr, hm, st, ions, ks, ext_partners)
This computes the total stress on the lattice.
Definition: stress.F90:186
subroutine stress_from_hubbard(namespace, gr, st, hm, space, rcell_volume, stress_hubbard)
Computes the contribution to the stress tensor from the Hubbard energy.
Definition: stress.F90:981
subroutine stress_from_xc_nlcc(rcell_volume, gr, st, ions, vxc, stress_xc_nlcc)
Computes the NLCC contribution to the stress tensor from the xc energy.
Definition: stress.F90:589
subroutine stress_from_pseudo_nonloc(gr, st, hm, ions, stress_ps_nl)
Computes the contribution to the stress tensor from the nonlocal part of the pseudopotentials.
Definition: stress.F90:677
subroutine stress_from_hartree(gr, space, volume, vh, grad_vh, ehartree, stress_Hartree)
Computes the contribution to the stress tensor from the Hartree energy.
Definition: stress.F90:509
subroutine, public output_stress(iunit, space_dim, stress_tensors, all_terms)
Definition: stress.F90:1075
subroutine stress_from_pseudo_local(gr, st, hm, ions, rho_total, vh, grad_vh, stress_ps_local)
Computes the contribution from the local part of the pseudopotential.
Definition: stress.F90:783
subroutine, public submesh_end(this)
Definition: submesh.F90:739
subroutine, public submesh_init(this, space, mesh, latt, center, rc)
Definition: submesh.F90:283
subroutine, public dsymmetrize_tensor_cart(symm, tensor, use_non_symmorphic)
Symmetric a rank-2 tensor defined in Cartesian space.
type(type_t), parameter, public type_cmplx
Definition: types.F90:134
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_t), public unit_gpa
For output pressure in GPa.
Definition: xc.F90:114
logical pure function, public xc_is_energy_functional(xcs)
Is one of the x or c functional is not an energy functional.
Definition: xc.F90:731
pure logical function, public in_family(family, xc_families)
Definition: xc.F90:623
A module that takes care of xc contribution from vdW interactions.
Definition: xc_vdw.F90:116
integer(int64), dimension(5), parameter, public d3_lib_options
VDWCORRECTION options that correspond to the DFT-D3 library.
Definition: xc_vdw.F90:169
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:168
Describes mesh distribution to nodes.
Definition: mesh.F90:186
A type storing the information and data about a pseudopotential.
Definition: ps.F90:184
The states_elec_t class contains all electronic wave functions.
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
Definition: submesh.F90:175
batches of electronic states
Definition: wfs_elec.F90:138
int true(void)