34 use,
intrinsic :: iso_fortran_env
80 integer,
parameter :: &
81 PERTURBATION_ELECTRIC = 1, &
88 class(perturbation_t),
pointer :: perturbation
98 real(real64) :: freq_factor(3)
99 real(real64),
allocatable :: omega(:)
100 type(lr_t),
allocatable :: lr(:,:,:)
101 complex(real64),
allocatable :: alpha_k(:, :, :, :)
103 complex(real64),
allocatable :: alpha_be_k(:, :, :, :)
105 logical :: calc_hyperpol
106 complex(real64) :: alpha(3, 3, 3)
107 complex(real64) :: alpha_be(3, 3, 3)
108 complex(real64) :: alpha0(3, 3, 3)
110 complex(real64) :: alpha_be0(3, 3, 3)
112 complex(real64) :: beta (3, 3, 3)
114 complex(real64) :: chi_para(3, 3)
115 complex(real64) :: chi_dia (3, 3)
116 complex(real64) :: magn(3)
119 logical :: force_no_kdotp
121 logical :: calc_rotatory
123 type(Born_charges_t) :: Born_charges(3)
124 logical :: occ_response
125 logical :: wfns_from_scratch
126 logical :: calc_magnetooptics
127 logical :: magnetooptics_nohvar
129 logical :: kpt_output
131 logical :: lrc_kernel
139 class(*),
intent(inout) :: system
140 logical,
intent(in) :: from_scratch
146 message(1) =
"CalculationMode = em_resp not implemented for multi-system calculations"
157 type(electrons_t),
intent(inout) :: sys
158 logical,
intent(in) :: fromScratch
160 type(em_resp_t) :: em_vars
161 type(sternheimer_t) :: sh, sh_kdotp, sh2, sh_kmo, sh_mo
162 type(lr_t) :: kdotp_lr(sys%space%dim, 1)
163 type(lr_t),
allocatable :: kdotp_em_lr2(:, :, :, :)
164 type(lr_t),
allocatable :: b_lr(:, :)
165 type(lr_t),
allocatable :: kb_lr(:, :, :), k2_lr(:, :, :)
166 type(lr_t),
allocatable :: ke_lr(:, :, :, :)
167 class(perturbation_t),
pointer :: pert_kdotp, pert2_none, pert_b
169 integer :: sigma, idir, idir2, ierr, iomega, ifactor
170 integer :: ierr_e(3), ierr_e2(3), nfactor_ke
171 character(len=100) :: str_tmp
172 logical :: complex_response, have_to_calculate, use_kdotp, opp_freq, &
173 exact_freq(3), complex_wfs, allocate_rho_em, allocate_rho_mo
174 logical :: magnetic_pert
176 real(real64) :: last_omega, frequency, dfrequency_eta
177 real(real64),
allocatable :: dl_eig(:,:,:)
178 complex(real64) :: zfrequency_eta, lrc_coef(sys%space%dim, sys%space%dim)
179 type(
restart_t) :: gs_restart, kdotp_restart
183 if (sys%hm%pcm%run_pcm)
then
187 if (sys%kpoints%use_symmetries)
then
191 if (sys%kpoints%reduced%npoints /= sys%kpoints%full%npoints)
then
197 select type(ptr=>em_vars%perturbation)
199 if (any(abs(em_vars%omega(1:em_vars%nomega)) >
m_epsilon))
then
204 em_vars%lrc_kernel = .false.
212 sys%st%restart_fixed_occ, is_complex = complex_response)
213 call gs_restart%end()
215 message(1) =
"Previous gs calculation is required."
224 message(1) =
'Info: Using real wavefunctions.'
226 message(1) =
'Info: Using complex wavefunctions.'
231 message(1) =
'Info: Setting up Hamiltonian for linear response'
233 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
235 use_kdotp = sys%space%is_periodic() .and. .not. em_vars%force_no_kdotp
239 message(1) =
"em_resp with kdotp can only be used with semiconducting smearing"
243 if (use_kdotp .and. sys%kpoints%use_symmetries .and. sys%space%periodic_dim < sys%space%dim)
then
244 message(1) =
"For mixed periodicity, the polarizability components along the non-periodic"
245 message(2) =
"directions are not symmetrized over the k-point symmetry operations."
251 message(1) =
"Reading kdotp wavefunctions for periodic directions."
256 message(1) =
"Unable to read kdotp wavefunctions."
257 message(2) =
"Previous kdotp calculation required."
261 do idir = 1, sys%space%periodic_dim
262 call lr_init(kdotp_lr(idir, 1))
263 call lr_allocate(kdotp_lr(idir, 1), sys%st, sys%gr, allocate_rho = .false.)
268 call kdotp_restart%open_dir(
wfs_tag_sigma(sys%namespace, str_tmp, 1), ierr)
270 call states_elec_load(kdotp_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
271 sys%st%restart_fixed_occ, ierr=ierr, lr=kdotp_lr(idir, 1))
273 call kdotp_restart%close_dir()
276 message(1) =
"Could not load kdotp wavefunctions from '"//trim(
wfs_tag_sigma(sys%namespace, str_tmp, 1))//
"'"
277 message(2) =
"Previous kdotp calculation required."
282 call kdotp_restart%end()
286 if (em_vars%calc_hyperpol) em_vars%nfactor = 3
289 if (em_vars%calc_hyperpol .or. any(abs(em_vars%omega(1:em_vars%nomega)) >
m_epsilon))
then
297 if (em_vars%calc_hyperpol .and. use_kdotp)
then
301 call pert2_none%setup_dir(1)
302 safe_allocate(kdotp_em_lr2(1:sys%space%periodic_dim, 1:sys%space%dim, 1:em_vars%nsigma, 1:em_vars%nfactor))
303 do ifactor = 1, em_vars%nfactor
304 do sigma = 1, em_vars%nsigma
305 do idir = 1, sys%space%periodic_dim
306 do idir2 = 1, sys%space%dim
307 call lr_init(kdotp_em_lr2(idir, idir2, sigma, ifactor))
308 call lr_allocate(kdotp_em_lr2(idir, idir2, sigma, ifactor), sys%st, sys%gr, allocate_rho = .false.)
313 call sternheimer_init(sh2, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
314 complex_response, set_ham_var = 0, set_last_occ_response = .false.)
315 call sternheimer_init(sh_kdotp, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
316 complex_response, set_ham_var = 0, set_last_occ_response = .
true.)
317 em_vars%occ_response = .
true.
318 safe_allocate(dl_eig(1:sys%st%nst, 1:sys%st%nik, 1:sys%space%periodic_dim))
323 if (em_vars%calc_magnetooptics)
then
324 if (em_vars%calc_hyperpol .and. use_kdotp)
then
325 message(1) =
"Hyperpolarizability and magnetooptics with kdotp are not compatible."
326 message(2) =
"Only calculation of hyperpolarizability will be performed."
328 em_vars%calc_magnetooptics = .false.
331 em_vars%freq_factor(1) =
m_one
332 em_vars%freq_factor(2) = -
m_one
336 magnetic_pert = .false.
337 select type(ptr => em_vars%perturbation)
340 if (use_kdotp)
call messages_experimental(
"Magnetic perturbation for periodic systems", namespace=sys%namespace)
341 magnetic_pert = .
true.
344 if (em_vars%calc_magnetooptics .or. magnetic_pert)
then
345 em_vars%occ_response = .false.
349 call pert2_none%setup_dir(1)
351 safe_allocate(k2_lr(1:sys%space%dim, 1:sys%space%dim, 1:1))
352 safe_allocate(kb_lr(1:sys%space%dim, 1:sys%space%dim, 1:1))
353 do idir = 1, sys%space%dim
354 do idir2 = 1, sys%space%dim
355 call lr_init(kb_lr(idir, idir2, 1))
356 call lr_allocate(kb_lr(idir, idir2, 1), sys%st, sys%gr, allocate_rho = .false.)
357 if (idir2 <= idir)
then
358 call lr_init(k2_lr(idir, idir2, 1))
359 call lr_allocate(k2_lr(idir, idir2, 1), sys%st, sys%gr, allocate_rho = .false.)
364 if (sys%space%periodic_dim < sys%space%dim)
then
365 if (magnetic_pert)
then
366 message(1) =
"All directions should be periodic for magnetic perturbations with kdotp."
368 message(1) =
"All directions should be periodic for magnetooptics with kdotp."
372 if (.not. complex_response)
then
373 do idir = 1, sys%space%dim
377 do idir = 1, sys%space%dim
381 call sternheimer_init(sh_kmo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
382 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
386 safe_allocate(em_vars%lr(1:sys%space%dim, 1:em_vars%nsigma, 1:em_vars%nfactor))
387 do ifactor = 1, em_vars%nfactor
388 call born_charges_init(em_vars%Born_charges(ifactor), sys%namespace, sys%ions%natoms, &
389 sys%st%val_charge, sys%st%qtot, sys%space%dim)
392 if (magnetic_pert .and. sys%st%d%nspin == 1 .and.
states_are_real(sys%st))
then
394 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
395 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
398 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
399 complex_response, set_last_occ_response = em_vars%occ_response)
403 if (em_vars%lrc_kernel .and. (.not. sh%add_hartree()) &
404 .and. (.not. sh%add_fxc()))
then
405 message(1) =
"Only the G = G'= 0 term of the LRC kernel is taken into account."
410 if (sys%st%system_grp%is_root())
then
415 allocate_rho_em = sh%add_fxc() .or. sh%add_hartree()
416 do ifactor = 1, em_vars%nfactor
417 do idir = 1, sys%space%dim
418 do sigma = 1, em_vars%nsigma
419 call lr_init(em_vars%lr(idir, sigma, ifactor))
420 call lr_allocate(em_vars%lr(idir, sigma, ifactor), sys%st, sys%gr, allocate_rho = allocate_rho_em)
425 select type(ptr=> em_vars%perturbation)
429 em_vars%kpt_output = .false.
431 if (.not. use_kdotp .or. sys%st%nik == 1) em_vars%kpt_output = .false.
433 if (em_vars%kpt_output)
then
434 safe_allocate(em_vars%alpha_k(1:sys%space%dim, 1:sys%space%dim, 1:em_vars%nfactor, 1:sys%st%nik))
437 if (em_vars%calc_magnetooptics)
then
438 if (em_vars%magnetooptics_nohvar)
then
439 call sternheimer_init(sh_mo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
440 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
442 call sternheimer_init(sh_mo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks, sys%mc, &
443 complex_response, set_last_occ_response = em_vars%occ_response)
447 allocate_rho_mo = sh_mo%add_fxc() .or. sh_mo%add_hartree()
448 safe_allocate(b_lr(1:sys%space%dim, 1))
449 do idir = 1, sys%space%dim
451 call lr_allocate(b_lr(idir, 1), sys%st, sys%gr, allocate_rho = allocate_rho_mo)
455 if (em_vars%kpt_output)
then
456 safe_allocate(em_vars%alpha_be_k(1:sys%space%dim, 1:sys%space%dim, 1:sys%space%dim, 1:sys%st%nik))
459 if (sys%kpoints%use_time_reversal .and. sys%kpoints%full%npoints > 1) nfactor_ke = em_vars%nfactor
460 safe_allocate(ke_lr(1:sys%space%dim, 1:sys%space%dim, 1:em_vars%nsigma, 1:nfactor_ke))
461 do idir = 1, sys%space%dim
462 do idir2 = 1, sys%space%dim
463 do sigma = 1, em_vars%nsigma
464 do ifactor = 1, nfactor_ke
465 call lr_init(ke_lr(idir, idir2, sigma, ifactor))
466 call lr_allocate(ke_lr(idir, idir2, sigma, ifactor), sys%st, sys%gr, allocate_rho = .false.)
478 do iomega = 1, em_vars%nomega
480 em_vars%ok(1:3) = .
true.
482 do ifactor = 1, em_vars%nfactor
483 frequency = em_vars%freq_factor(ifactor)*em_vars%omega(iomega)
484 zfrequency_eta = cmplx(frequency, em_vars%eta, real64)
485 if (em_vars%calc_magnetooptics .and. ifactor == 2) zfrequency_eta = frequency -
m_zi * em_vars%eta
486 dfrequency_eta = real(zfrequency_eta, real64)
488 if (abs(frequency) <
m_epsilon .and. em_vars%calc_magnetooptics .and. use_kdotp)
then
489 message(1) =
"Magnetooptical response with kdotp requires non-zero frequency."
497 have_to_calculate = .
true.
502 if (iomega > 1 .and. abs(em_vars%freq_factor(ifactor)) <=
m_epsilon) have_to_calculate = .false.
504 if (ifactor > 1 .and. (.not. em_vars%calc_magnetooptics))
then
507 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
510 do idir = 1, sys%space%dim
511 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, ifactor - 1), em_vars%lr(idir, 1, ifactor))
512 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, ifactor - 1), em_vars%lr(idir, 2, ifactor))
514 if (em_vars%calc_hyperpol .and. use_kdotp)
then
515 do idir2 = 1, sys%space%periodic_dim
516 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, ifactor - 1), &
517 kdotp_em_lr2(idir, idir2, 1, ifactor))
518 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, ifactor - 1), &
519 kdotp_em_lr2(idir, idir2, 2, ifactor))
524 have_to_calculate = .false.
529 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
532 do idir = 1, sys%space%dim
533 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, ifactor - 1), em_vars%lr(idir, 2, ifactor))
534 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, ifactor - 1), em_vars%lr(idir, 1, ifactor))
536 if (em_vars%calc_hyperpol .and. use_kdotp)
then
537 do idir2 = 1, sys%space%periodic_dim
538 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, ifactor - 1), &
539 kdotp_em_lr2(idir, idir2, 2, ifactor))
540 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, ifactor - 1), &
541 kdotp_em_lr2(idir, idir2, 1, ifactor))
546 have_to_calculate = .false.
552 if (iomega > 1 .and. ifactor == 1 .and. (.not. em_vars%calc_magnetooptics))
then
555 if (have_to_calculate .and. abs(frequency - last_omega) <
m_epsilon)
then
557 do idir = 1, sys%space%dim
558 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, em_vars%nfactor), em_vars%lr(idir, 1, 1))
559 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, em_vars%nfactor), em_vars%lr(idir, 2, 1))
561 if (em_vars%calc_hyperpol .and. use_kdotp)
then
562 do idir2 = 1, sys%space%periodic_dim
563 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, em_vars%nfactor), &
564 kdotp_em_lr2(idir, idir2, 1, 1))
565 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, em_vars%nfactor), &
566 kdotp_em_lr2(idir, idir2, 2, 1))
571 have_to_calculate = .false.
576 if (have_to_calculate .and. abs(frequency + last_omega) <
m_epsilon)
then
578 do idir = 1, sys%space%dim
579 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, em_vars%nfactor), em_vars%lr(idir, 2, 1))
580 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, em_vars%nfactor), em_vars%lr(idir, 1, 1))
582 if (em_vars%calc_hyperpol .and. use_kdotp)
then
583 do idir2 = 1, sys%space%periodic_dim
584 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, em_vars%nfactor), &
585 kdotp_em_lr2(idir, idir2, 2, 1))
586 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, em_vars%nfactor), &
587 kdotp_em_lr2(idir, idir2, 1, 1))
592 have_to_calculate = .false.
598 if (have_to_calculate)
then
600 exact_freq(:) = .false.
603 call drun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
606 call zrun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
612 if (.not. have_to_calculate) cycle
615 call dcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
618 call zcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
630 last_omega = em_vars%freq_factor(em_vars%nfactor) * em_vars%omega(iomega)
634 do idir = 1, sys%space%dim
635 do sigma = 1, em_vars%nsigma
636 do ifactor = 1, em_vars%nfactor
637 call lr_dealloc(em_vars%lr(idir, sigma, ifactor))
643 deallocate(em_vars%perturbation)
646 do idir = 1, sys%space%periodic_dim
651 if (em_vars%calc_hyperpol .and. use_kdotp)
then
654 safe_deallocate_p(pert_kdotp)
655 safe_deallocate_p(pert2_none)
656 do idir = 1, sys%space%periodic_dim
657 do idir2 = 1, sys%space%periodic_dim
658 do sigma = 1, em_vars%nsigma
659 do ifactor = 1, em_vars%nfactor
660 call lr_dealloc(kdotp_em_lr2(idir, idir2, sigma, ifactor))
665 safe_deallocate_a(kdotp_em_lr2)
666 safe_deallocate_a(dl_eig)
669 if (em_vars%kpt_output)
then
670 safe_deallocate_a(em_vars%alpha_k)
673 if (em_vars%calc_magnetooptics .or. magnetic_pert)
then
675 safe_deallocate_p(pert2_none)
677 do idir = 1, sys%space%dim
678 do idir2 = 1, sys%space%dim
680 if (idir2 <= idir)
call lr_dealloc(k2_lr(idir, idir2, 1))
683 safe_deallocate_a(k2_lr)
684 safe_deallocate_a(kb_lr)
688 if (em_vars%calc_magnetooptics)
then
691 do idir = 1, sys%space%dim
694 safe_deallocate_a(b_lr)
697 do idir = 1, sys%space%dim
698 do idir2 = 1, sys%space%dim
699 do sigma = 1, em_vars%nsigma
700 do ifactor = 1, nfactor_ke
701 call lr_dealloc(ke_lr(idir, idir2, sigma, ifactor))
706 safe_deallocate_a(ke_lr)
707 if (em_vars%kpt_output)
then
708 safe_deallocate_a(em_vars%alpha_be_k)
711 safe_deallocate_p(pert_b)
715 safe_deallocate_a(em_vars%omega)
716 safe_deallocate_a(em_vars%lr)
717 do ifactor = 1, em_vars%nfactor
729 integer :: nrow, irow, nfreqs_in_row, ifreq, istep, perturb_type
730 real(real64) :: omega_ini, omega_fin, domega
761 if (
parse_block(sys%namespace,
'EMFreqs', blk) == 0)
then
769 if (nfreqs_in_row < 1)
then
770 message(1) =
"EMFreqs: invalid number of frequencies."
773 em_vars%nomega = em_vars%nomega + nfreqs_in_row
776 safe_allocate(em_vars%omega(1:em_vars%nomega))
783 if (nfreqs_in_row > 1)
then
785 domega = (omega_fin - omega_ini)/(nfreqs_in_row -
m_one)
786 do istep = 0, nfreqs_in_row-1
787 em_vars%omega(ifreq + istep) = omega_ini + domega*istep
789 ifreq = ifreq + nfreqs_in_row
791 em_vars%omega(ifreq) = omega_ini
809 if (freq_sort)
call sort(em_vars%omega)
814 safe_allocate(em_vars%omega(1:em_vars%nomega))
832 message(1) =
"EMEta cannot be negative."
837 em_vars%calc_hyperpol = .false.
838 em_vars%freq_factor(1:3) =
m_one
839 em_vars%calc_magnetooptics = .false.
840 em_vars%magnetooptics_nohvar = .
true.
841 em_vars%kpt_output = .false.
857 call parse_variable(sys%namespace,
'EMPerturbationType', perturbation_electric, perturb_type)
860 select case(perturb_type)
861 case(perturbation_electric)
871 select type(ptr=>em_vars%perturbation)
882 call parse_variable(sys%namespace,
'EMCalcRotatoryResponse', .false., em_vars%calc_rotatory)
896 if (
parse_block(sys%namespace,
'EMHyperpol', blk) == 0)
then
903 if (abs(sum(em_vars%freq_factor(1:3))) >
m_epsilon)
then
904 message(1) =
"Frequency factors specified by EMHyperpol must sum to zero."
908 em_vars%calc_hyperpol = .
true.
918 call parse_variable(sys%namespace,
'EMCalcMagnetooptics', .false., em_vars%calc_magnetooptics)
928 call parse_variable(sys%namespace,
'EMMagnetoopticsNoHVar', .
true., em_vars%magnetooptics_nohvar)
939 call parse_variable(sys%namespace,
'EMKPointOutput', .false., em_vars%kpt_output)
955 call parse_variable(sys%namespace,
'EMForceNoKdotP', .false., em_vars%force_no_kdotp)
965 call parse_variable(sys%namespace,
'EMCalcBornCharges', .false., em_vars%calc_Born)
966 if (em_vars%calc_Born)
call messages_experimental(
"Calculation of Born effective charges", namespace=sys%namespace)
979 call parse_variable(sys%namespace,
'EMOccupiedResponse', .false., em_vars%occ_response)
981 message(1) =
"EMOccupiedResponse cannot be used if there are partial occupations."
995 call parse_variable(sys%namespace,
'EMWavefunctionsFromScratch', .false., em_vars%wfns_from_scratch)
1007 call em_vars%perturbation%info()
1008 select type(ptr=>em_vars%perturbation)
1010 if (em_vars%calc_hyperpol)
then
1020 message(1) =
'Wavefunctions type: Real'
1022 message(1) =
'Wavefunctions type: Complex'
1026 write(
message(1),
'(a,i3,a)')
'Calculating response for ', em_vars%nomega,
' frequencies.'
1038#include "em_resp_inc.F90"
1041#include "complex.F90"
1042#include "em_resp_inc.F90"
1049 subroutine em_resp_output(st, namespace, space, gr, hm, ions, outp, sh, em_vars, iomega, ifactor)
1052 class(
space_t),
intent(in) :: space
1053 type(
grid_t),
intent(in) :: gr
1055 type(
ions_t),
intent(in) :: ions
1058 type(
em_resp_t),
intent(inout) :: em_vars
1059 integer,
intent(in) :: iomega
1060 integer,
intent(in) :: ifactor
1062 integer :: iunit, idir
1063 character(len=80) :: dirname, str_tmp
1064 character(len=24) :: warning
1065 logical :: use_kdotp
1066 complex(real64) :: epsilon(space%dim, space%dim)
1070 use_kdotp = space%is_periodic() .and. .not. em_vars%force_no_kdotp
1075 if (.not. em_vars%ok(ifactor)) warning =
" WARNING: not converged"
1079 write(dirname,
'(a, a)')
em_resp_dir//
'freq_', trim(str_tmp)
1080 call io_mkdir(trim(dirname), namespace)
1082 if (sh%has_photons .and. st%system_grp%is_root())
then
1083 iunit =
io_open(trim(dirname)//
'/photon_coord_q', namespace, action=
'write')
1085 write(iunit,
'(a)')
' Re Im'
1086 do idir = 1, space%dim
1095 select type(ptr=>em_vars%perturbation)
1097 if ((.not. em_vars%calc_magnetooptics) .or. ifactor == 1)
then
1099 if (em_vars%calc_Born)
then
1100 call born_output_charges(em_vars%born_charges(ifactor), ions%atom, ions%charge, ions%natoms, &
1101 namespace, space%dim, dirname, write_real = em_vars%eta <
m_epsilon)
1104 if (space%periodic_dim == space%dim)
then
1108 if ((.not. space%is_periodic() .or. em_vars%force_no_kdotp) .and. em_vars%calc_rotatory)
then
1129 if (.not. st%system_grp%is_root())
return
1133 iunit =
io_open(trim(dirname)//
'/eta', namespace, action=
'write')
1147 integer,
intent(in) :: out_file
1149 character(len=80) :: header_string
1150 integer :: ii, idir, kdir
1152 if (.not. st%system_grp%is_root())
return
1157 write(out_file,
'(a1, a20)', advance =
'no')
'#',
str_center(
"Energy", 20)
1158 write(out_file,
'(a20)', advance =
'no')
str_center(
"(1/3)*Tr[sigma]", 20)
1159 write(out_file,
'(a20)', advance =
'no')
str_center(
"Anisotropy[sigma]", 20)
1161 do idir = 1, space%dim
1162 do kdir = 1, space%dim
1163 write(header_string,
'(a6,i1,a1,i1,a1)')
'sigma(', idir,
',', kdir,
')'
1164 write(out_file,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1168 write(out_file,
'(a)', advance =
'no') trim(warning)
1171 do ii = 1, 2 + space%dim**2
1182 real(real64) :: cross(space%dim, space%dim), crossp(space%dim, space%dim)
1183 real(real64) :: cross_sum, crossp_sum, anisotropy
1184 integer :: idir, idir2
1186 if (.not. st%system_grp%is_root())
return
1190 iunit =
io_open(trim(dirname)//
'/alpha', namespace, action=
'write')
1192 write(iunit,
'(4a)')
'# Polarizability tensor [', trim(
units_abbrev(
units_out%polarizability)),
']', trim(warning)
1193 call output_tensor(real(em_vars%alpha(:, :, ifactor), real64), space%dim,
units_out%polarizability, iunit=iunit)
1199 cross(1:space%dim, 1:space%dim) = aimag(em_vars%alpha(1:space%dim, 1:space%dim, ifactor)) * &
1200 em_vars%freq_factor(ifactor) * em_vars%omega(iomega) * (
m_four *
m_pi /
p_c)
1202 do idir = 1, space%dim
1203 do idir2 = 1, space%dim
1208 iunit =
io_open(trim(dirname)//
'/cross_section', namespace, action=
'write')
1210 crossp(1:space%dim, 1:space%dim) = matmul(cross(1:space%dim, 1:space%dim), cross(1:space%dim, 1:space%dim))
1214 do idir = 1, space%dim
1215 cross_sum = cross_sum + cross(idir, idir)
1216 crossp_sum = crossp_sum + crossp(idir, idir)
1219 anisotropy = crossp_sum -
m_third * cross_sum**2
1222 write(iunit,
'(3e20.8)', advance =
'no') &
1225 do idir = 1, space%dim
1226 do idir2 = 1, space%dim
1227 write(iunit,
'(e20.8)', advance =
'no') cross(idir, idir2)
1230 write(iunit,
'(a)', advance =
'yes')
1242 integer :: idir, idir1, ik
1243 character(len=80) :: header_string
1244 complex(real64),
allocatable :: epsilon_k(:, :, :)
1246 if (.not. st%system_grp%is_root())
return
1250 iunit =
io_open(trim(dirname)//
'/epsilon', namespace, action=
'write')
1252 epsilon(1:space%dim, 1:space%dim) = &
1253 4 *
m_pi * em_vars%alpha(1:space%dim, 1:space%dim, ifactor) / ions%latt%rcell_volume
1254 do idir = 1, space%dim
1255 epsilon(idir, idir) = epsilon(idir, idir) +
m_one
1258 write(iunit,
'(2a)')
'# Real part of dielectric constant', trim(warning)
1259 call output_tensor(real(epsilon(1:space%dim, 1:space%dim), real64), space%dim,
unit_one, iunit=iunit)
1261 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1264 if (em_vars%lrc_kernel)
then
1266 write(iunit,
'(a)')
'# Without G = G'' = 0 term of the LRC kernel'
1268 epsilon(1:space%dim, 1:space%dim) = &
1269 4 *
m_pi * em_vars%alpha0(1:space%dim, 1:space%dim, ifactor) / ions%latt%rcell_volume
1270 do idir = 1, space%dim
1271 epsilon(idir, idir) = epsilon(idir, idir) +
m_one
1274 write(iunit,
'(a)')
'# Real part of dielectric constant'
1275 call output_tensor(real(epsilon(1:space%dim, 1:space%dim), real64), space%dim,
unit_one, iunit=iunit)
1277 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1283 if (em_vars%kpt_output)
then
1284 safe_allocate(epsilon_k(1:space%dim, 1:space%dim, 1:hm%kpoints%reduced%npoints))
1285 do ik = 1, hm%kpoints%reduced%npoints
1286 do idir = 1, space%dim
1287 do idir1 = 1, space%dim
1288 epsilon_k(idir, idir1, ik) =
m_four *
m_pi * em_vars%alpha_k(idir, idir1, ifactor, ik) / ions%latt%rcell_volume
1292 iunit =
io_open(trim(dirname)//
'/epsilon_k_re', namespace, action=
'write')
1294 write(iunit,
'(a)')
'# Real part of dielectric constant'
1295 write(iunit,
'(a10)', advance =
'no')
'# index '
1296 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1297 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1298 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1299 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1301 do idir = 1, space%dim
1302 do idir1 = 1, space%dim
1303 write(header_string,
'(a7,i1,a1,i1,a1)')
'Re eps(', idir,
',', idir1,
')'
1304 write(iunit,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1309 do ik = 1, hm%kpoints%reduced%npoints
1310 write(iunit,
'(i8)', advance =
'no') ik
1311 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1312 do idir = 1, space%dim
1313 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1315 do idir = 1, space%dim
1316 do idir1 = 1, space%dim
1317 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_k(idir, idir1, ik), real64)
1324 iunit =
io_open(trim(dirname)//
'/epsilon_k_im', namespace, action=
'write')
1326 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1327 write(iunit,
'(a10)', advance =
'no')
'# index '
1328 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1329 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1330 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1331 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1333 do idir = 1, space%dim
1334 do idir1 = 1, space%dim
1335 write(header_string,
'(a7,i1,a1,i1,a1)')
'Im eps(', idir,
',', idir1,
')'
1336 write(iunit,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1341 do ik = 1, hm%kpoints%reduced%npoints
1342 write(iunit,
'(i8)', advance =
'no') ik
1343 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1344 do idir = 1, space%dim
1345 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1347 do idir = 1, space%dim
1348 do idir1 = 1, space%dim
1349 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_k(idir, idir1, ik))
1355 safe_deallocate_a(epsilon_k)
1365 character(len=80) :: dirname1
1367 if (.not. st%system_grp%is_root())
return
1371 select type(ptr=>em_vars%perturbation)
1374 call io_mkdir(trim(dirname1), namespace)
1375 iunit =
io_open(trim(dirname1)//
'/susceptibility', namespace, action=
'write')
1377 iunit =
io_open(trim(dirname)//
'/susceptibility', namespace, action=
'write')
1382 if (.not. use_kdotp)
then
1383 write(iunit,
'(2a)')
'# Paramagnetic contribution to the susceptibility tensor [ppm a.u.]'
1385 write(iunit,
'(1x)')
1387 write(iunit,
'(2a)')
'# Diamagnetic contribution to the susceptibility tensor [ppm a.u.]'
1389 write(iunit,
'(1x)')
1392 write(iunit,
'(2a)')
'# Total susceptibility tensor [ppm a.u.]', trim(warning)
1393 call output_tensor(real(em_vars%chi_para(:, :) + em_vars%chi_dia(:,:), real64) , &
1395 write(iunit,
'(1x)')
1399 if (.not. use_kdotp)
then
1400 write(iunit,
'(2a)')
'# Paramagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1402 write(iunit,
'(1x)')
1404 write(iunit,
'(2a)')
'# Diamagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1406 write(iunit,
'(1x)')
1409 write(iunit,
'(2a)')
'# Total susceptibility tensor [ppm cgs / mol]'
1410 call output_tensor(real(em_vars%chi_para(:, :) + em_vars%chi_dia(:,:), real64), &
1412 write(iunit,
'(1x)')
1416 write(iunit,
'(1a)')
'# Magnetization [ppm a.u.]'
1429 integer :: idir, isigma
1433 do idir = 1, space%dim
1436 do isigma = 1, em_vars%nsigma
1437 call zoutput_lr(outp, namespace, space, dirname, st, gr, em_vars%lr(idir, isigma, ifactor), idir, isigma, ions, &
1442 do isigma = 1, em_vars%nsigma
1443 call doutput_lr(outp, namespace, space, dirname, st, gr, em_vars%lr(idir, isigma, ifactor), idir, isigma, ions, &
1463 complex(real64) :: dic
1464 complex(real64),
allocatable :: psi(:, :, :, :)
1470 message(1) =
"Info: Calculating rotatory response."
1475 safe_allocate(psi(1:gr%np_part, 1:st%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1480 do idir = 1, space%dim
1481 call angular_momentum%setup_dir(idir)
1483 + angular_momentum%zexpectation_value(namespace, space, gr, hm, st, psi, &
1484 em_vars%lr(idir, 1, ifactor)%zdl_psi) &
1485 + angular_momentum%zexpectation_value(namespace, space, gr, hm, st, &
1486 em_vars%lr(idir, 2, ifactor)%zdl_psi, psi)
1489 safe_deallocate_a(psi)
1491 safe_deallocate_p(angular_momentum)
1495 if (st%system_grp%is_root())
then
1497 iunit =
io_open(trim(dirname)//
'/rotatory_strength', namespace, action=
'write')
1500 write(iunit,
'(a1,a20,a20,a20)')
'#',
str_center(
"Energy", 20),
str_center(
"R", 20),
str_center(
"Re[beta]", 20)
1506 if (abs(em_vars%omega(iomega)) >
m_epsilon) ff = real(dic, real64) /(
m_three*em_vars%omega(iomega))
1522 complex(real64) :: epsilon_m(4), diff(4), eps_mk(space%dim)
1524 if (.not. st%system_grp%is_root())
return
1529 assert(space%dim == 3)
1532 do idir = 1, space%dim
1536 diff(4) = (diff(1) + diff(2) + diff(3)) /
m_three
1538 iunit =
io_open(trim(dirname)//
'/alpha_mo', namespace, action=
'write')
1540 write(iunit,
'(a1, a25)', advance =
'no')
'#',
str_center(
" ", 25)
1541 write(iunit,
'(a20)', advance =
'no')
str_center(
" yz,x = -zy,x", 20)
1542 write(iunit,
'(a20)', advance =
'no')
str_center(
" zx,y = -xz,y", 20)
1543 write(iunit,
'(a20)', advance =
'no')
str_center(
" xy,z = -yx,z", 20)
1544 write(iunit,
'(a20)', advance =
'no')
str_center(
" Average", 20)
1545 write(iunit,
'(a)', advance =
'no') trim(warning)
1548 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re alpha [a.u.]", 25)
1549 do idir = 1, space%dim + 1
1550 write(iunit,
'(e20.8)', advance =
'no') real(diff(idir), real64)
1554 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im alpha [a.u.]", 25)
1555 do idir = 1, space%dim + 1
1556 write(iunit,
'(e20.8)', advance =
'no') aimag(diff(idir))
1560 if (space%is_periodic())
then
1562 assert(space%periodic_dim == 3)
1564 do idir = 1, space%dim
1565 epsilon_m(idir) = 4 *
m_pi * diff(idir) / ions%latt%rcell_volume
1567 epsilon_m(4) = 4 *
m_pi * diff(4) / ions%latt%rcell_volume
1569 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re epsilon (B = 1 a.u.)", 25)
1570 do idir = 1, space%dim + 1
1571 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_m(idir), real64)
1575 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im epsilon (B = 1 a.u.)", 25)
1576 do idir = 1, space%dim + 1
1577 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_m(idir))
1581 if (em_vars%lrc_kernel)
then
1583 write(iunit,
'(a)')
'# Without the G = G'' = 0 term of the LRC kernel'
1587 do idir = 1, space%dim
1591 epsilon_m(idir) = 4 *
m_pi * diff(idir) / ions%latt%rcell_volume
1593 diff(4) = (diff(1) + diff(2) + diff(3)) /
m_three
1594 epsilon_m(4) = 4 *
m_pi * diff(4) / ions%latt%rcell_volume
1596 write(iunit,
'(a1, a25)', advance =
'no')
'#',
str_center(
" ", 25)
1597 write(iunit,
'(a20)', advance =
'no')
str_center(
" yz,x = -zy,x", 20)
1598 write(iunit,
'(a20)', advance =
'no')
str_center(
" zx,y = -xz,y", 20)
1599 write(iunit,
'(a20)', advance =
'no')
str_center(
" xy,z = -yx,z", 20)
1600 write(iunit,
'(a20)', advance =
'no')
str_center(
" Average", 20)
1603 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re alpha [a.u.]", 25)
1604 do idir = 1, space%dim + 1
1605 write(iunit,
'(e20.8)', advance =
'no') real(diff(idir), real64)
1609 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im alpha [a.u.]", 25)
1610 do idir = 1, space%dim + 1
1611 write(iunit,
'(e20.8)', advance =
'no') aimag(diff(idir))
1615 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re epsilon (B = 1 a.u.)", 25)
1616 do idir = 1, space%dim + 1
1617 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_m(idir), real64)
1621 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im epsilon (B = 1 a.u.)", 25)
1622 do idir = 1, space%dim + 1
1623 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_m(idir))
1630 if (space%is_periodic() .and. em_vars%kpt_output)
then
1631 iunit =
io_open(trim(dirname)//
'/epsilon_mo_k', namespace, action=
'write')
1633 write(iunit,
'(a)')
'# Contribution to dielectric tensor for B = 1 a.u.'
1634 write(iunit,
'(a10)', advance =
'no')
'# index '
1635 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1636 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1637 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1638 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1639 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_yz,x", 20)
1640 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_zx,y", 20)
1641 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_xy,z", 20)
1642 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_yz,x", 20)
1643 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_zx,y", 20)
1644 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_xy,z", 20)
1647 do ik = 1, hm%kpoints%reduced%npoints
1648 write(iunit,
'(i8)', advance =
'no') ik
1649 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1650 do idir = 1, space%dim
1652 em_vars%alpha_be_k(
magn_dir(idir, 2),
magn_dir(idir, 1), idir, ik)) / ions%latt%rcell_volume
1655 do idir = 1, space%dim
1656 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1658 do idir = 1, space%dim
1659 write(iunit,
'(e20.8)', advance =
'no') real(eps_mk(idir), real64)
1661 do idir = 1, space%dim
1662 write(iunit,
'(e20.8)', advance =
'no') aimag(eps_mk(idir))
1679 class(
box_t),
intent(in) :: box
1680 complex(real64),
intent(in) :: beta(:, :, :)
1681 real(real64),
intent(in) :: freq_factor(:)
1682 logical,
intent(in) :: converged
1683 character(len=*),
intent(in) :: dirname
1686 complex(real64) :: bpar(1:box%dim), bper(1:box%dim), bk(1:box%dim)
1687 complex(real64) :: HRS_VV, HRS_HV
1688 integer :: ii, jj, kk, iunit
1693 iunit =
io_open(trim(dirname)//
'/beta', namespace, action=
'write')
1695 write(iunit,
'(a,3(f4.1,a),2a)', advance=
'no')
'First hyperpolarizability tensor: beta(', &
1696 freq_factor(1),
', ', freq_factor(2),
', ', freq_factor(3),
') [', &
1698 if (.not. converged)
write(iunit,
'(a)', advance=
'no')
' WARNING: not converged'
1705 write(iunit,
'(a,e20.8,e20.8)')
'beta '// &
1713 if (box%dim == 3)
then
1719 bpar(ii) = bpar(ii) + beta(ii, jj, jj) + beta(jj, ii, jj) + beta(jj, jj, ii)
1720 bper(ii) = bper(ii) +
m_two*beta(ii, jj, jj) -
m_three*beta(jj, ii, jj) +
m_two*beta(jj, jj, ii)
1728 bk(1:box%dim) =
m_three*
m_half*(bpar(1:box%dim) - bper(1:box%dim))
1731 write(iunit,
'(a, 2e20.8)')
'beta // '//
index2axis(ii), &
1739 write(iunit,
'(a, 2e20.8)')
'beta _L '//
index2axis(ii), &
1747 write(iunit,
'(a, 2e20.8)')
'beta k '//
index2axis(ii), &
1755 write(iunit,
'(a)')
'beta for liquid- or gas-phase hyper-Rayleigh scattering:'
1756 write(iunit,
'(a, 2e20.8)')
'VV polarization ', &
1759 write(iunit,
'(a, 2e20.8)')
'HV polarization ', &
1775 class(
box_t),
intent(in) :: box
1776 complex(real64),
intent(in) :: beta(:, :, :)
1777 complex(real64),
intent(out) :: HRS_VV, HRS_HV
1779 complex(real64) :: HRS_A, HRS_B, HRS_C, HRS_D, HRS_E
1780 complex(real64) :: HRS_B1, HRS_B2, HRS_C1, HRS_C2, HRS_C3, HRS_D1, HRS_D2, HRS_D3, HRS_E1, HRS_E2
1788 hrs_a = hrs_a + beta(ii,ii,ii)**2
1796 hrs_b = hrs_b + beta(ii,ii,ii) * (beta(ii,jj,jj) + beta(jj,ii,jj) + beta(jj,jj,ii))
1797 hrs_c = hrs_c + (beta(ii,ii,jj) + beta(ii,jj,ii) + beta(jj,ii,ii))**2
1802 hrs_d = (beta(1,1,2) + beta(1,2,1) + beta(2,1,1)) * (beta(2,3,3) + beta(3,2,3) + beta(3,3,2)) &
1803 + (beta(2,2,3) + beta(2,3,2) + beta(3,2,2)) * (beta(3,1,1) + beta(1,3,1) + beta(1,1,3)) &
1804 + (beta(3,3,1) + beta(3,1,3) + beta(1,3,3)) * (beta(1,2,2) + beta(2,1,2) + beta(2,2,1))
1806 hrs_e = (beta(1,2,3) + beta(1,3,2) + beta(2,1,3) + beta(2,3,1) + beta(3,1,2) + beta(3,2,1))**2
1808 hrs_vv = (
m_one / 7.0_real64) * hrs_a &
1809 + (
m_two / 35.0_real64) * hrs_b &
1810 + (
m_one / 35.0_real64) * hrs_c &
1811 + (
m_two / 105.0_real64) * hrs_d &
1812 + (
m_one / 105.0_real64) * hrs_e
1823 hrs_b1 = hrs_b1 + beta(ii,ii,ii) * beta(ii,jj,jj)
1824 hrs_b2 = hrs_b2 + beta(ii,ii,ii) * (beta(jj,ii,jj) + beta(jj,jj,ii))
1825 hrs_c1 = hrs_c1 + (beta(ii,ii,jj) + beta(ii,jj,ii))**2
1826 hrs_c2 = hrs_c2 + beta(jj,ii,ii) * (beta(ii,ii,jj) + beta(ii,jj,ii))
1827 hrs_c3 = hrs_c3 + beta(jj,ii,ii)**2
1832 hrs_d1 = (beta(1,1,2) + beta(1,2,1) + beta(2,1,1)) * (beta(3,2,3) + beta(3,3,2)) &
1833 + (beta(2,2,3) + beta(2,3,2) + beta(3,2,2)) * (beta(1,3,1) + beta(1,1,3)) &
1834 + (beta(3,3,1) + beta(3,1,3) + beta(1,3,3)) * (beta(2,1,2) + beta(2,2,1))
1835 hrs_d2 = (beta(1,1,2) + beta(1,2,1)) * beta(2,3,3) &
1836 + (beta(2,2,3) + beta(2,3,2)) * beta(3,1,1) &
1837 + (beta(3,3,1) + beta(3,1,3)) * beta(1,2,2)
1838 hrs_d3 = beta(2,1,1) * beta(2,3,3) &
1839 + beta(3,2,2) * beta(3,1,1) &
1840 + beta(1,3,3) * beta(1,2,2)
1842 hrs_e1 = (beta(1,2,3) + beta(1,3,2))**2 &
1843 + (beta(2,1,3) + beta(2,3,1))**2 &
1844 + (beta(3,1,2) + beta(3,2,1))**2
1846 hrs_e2 = (beta(1,2,3) + beta(1,3,2)) * (beta(2,1,3) + beta(2,3,1)) &
1847 + (beta(2,1,3) + beta(2,3,1)) * (beta(3,1,2) + beta(3,2,1)) &
1848 + (beta(3,1,2) + beta(3,2,1)) * (beta(1,2,3) + beta(1,3,2))
1850 hrs_hv = (
m_one / 35.0_real64) * hrs_a &
1851 + (
m_four / 105.0_real64) * hrs_b1 &
1852 - (
m_one / 35.0_real64) * hrs_b2 &
1853 + (
m_two / 105.0_real64) * hrs_c1 &
1854 - (
m_one / 35.0_real64) * hrs_c2 &
1855 + (
m_three / 35.0_real64) * hrs_c3 &
1856 - (
m_one / 105.0_real64) * hrs_d1 &
1857 - (
m_one / 105.0_real64) * hrs_d2 &
1858 + (
m_two / 35.0_real64) * hrs_d3 &
1859 + (
m_one / 35.0_real64) * hrs_e1 &
1860 - (
m_one / 105.0_real64) * hrs_e2
subroutine out_dielectric_constant()
epsilon = 1 + 4 * pi * alpha/volume
subroutine calc_beta_hrs(box, beta, HRS_VV, HRS_HV)
calculate hyper-Rayleigh scattering hyperpolarizabilities SJ Cyvin, JE Rauch, and JC Decius,...
subroutine out_circular_dichroism()
See D Varsano, LA Espinosa Leal, Xavier Andrade, MAL Marques, Rosa di Felice, Angel Rubio,...
subroutine out_magnetooptics
subroutine out_susceptibility()
subroutine dcalc_properties_linear(em_vars, namespace, space, gr, kpoints, st, hm, xc, ions, outp)
subroutine out_wfn_and_densities()
subroutine drun_sternheimer(em_vars, namespace, space, gr, kpoints, st, hm, mc, ions)
subroutine out_polarizability()
subroutine dcalc_properties_nonlinear(em_vars, namespace, space, gr, st, hm, xc)
subroutine zrun_sternheimer(em_vars, namespace, space, gr, kpoints, st, hm, mc, ions)
subroutine cross_section_header(out_file)
Note: this should be in spectrum.F90.
subroutine zcalc_properties_nonlinear(em_vars, namespace, space, gr, st, hm, xc)
subroutine zcalc_properties_linear(em_vars, namespace, space, gr, kpoints, st, hm, xc, ions, outp)
This is the common interface to a sorting routine. It performs the shell algorithm,...
subroutine, public born_charges_end(this)
subroutine, public born_output_charges(this, atom, charge, natoms, namespace, dim, dirname, write_real)
subroutine, public born_charges_init(this, namespace, natoms, val_charge, qtot, dim)
integer pure function, public magn_dir(dir, ind)
character(len=12) function, public freq2str(freq)
integer, parameter perturbation_magnetic
subroutine em_resp_run_legacy(sys, fromScratch)
subroutine, public out_hyperpolarizability(box, beta, freq_factor, converged, dirname, namespace)
Ref: David M Bishop, Rev Mod Phys 62, 343 (1990) beta generalized to lack of Kleinman symmetry.
subroutine, public em_resp_run(system, from_scratch)
subroutine em_resp_output(st, namespace, space, gr, hm, ions, outp, sh, em_vars, iomega, ifactor)
integer, parameter perturbation_none
real(real64), parameter, public m_two
real(real64), parameter, public m_huge
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_third
real(real64), parameter, public m_pi
some mathematical constants
complex(real64), parameter, public m_z0
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
character(len= *), parameter, public em_resp_dir
real(real64), parameter, public m_half
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
real(real64), parameter, public m_one
real(real64), parameter, public m_three
real(real64), parameter, public m_five
This module implements the underlying real-space grid.
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
character(len=100) function, public kdotp_wfs_tag(dir, dir2)
subroutine, public zlr_orth_response(mesh, st, lr, omega)
subroutine, public lr_copy(st, mesh, src, dest)
subroutine, public lr_allocate(lr, st, mesh, allocate_rho)
subroutine, public lr_init(lr)
subroutine, public lr_dealloc(lr)
subroutine, public dlr_orth_response(mesh, st, lr, omega)
System information (time, memory, sysname)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
character(len=512), private msg
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
character(len=68), parameter, public hyphens
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module handles the communicators for the various parallelization strategies.
This module implements the basic mulsisystem class, a container system for other systems.
this module contains the low-level part of the output system
this module contains the output system
subroutine, public zoutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
subroutine, public doutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
integer, parameter, public restart_kdotp
integer, parameter, public restart_gs
integer, parameter, public restart_type_load
integer, parameter, public smear_fixed_occ
logical pure function, public smear_is_semiconducting(this)
This module is intended to contain "only mathematical" functions and procedures.
pure logical function, public states_are_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_look_and_load(restart, namespace, space, st, mesh, kpoints, fixed_occ, is_complex, packed)
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, fixed_occ, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
character(len=100) function, public wfs_tag_sigma(namespace, base_name, isigma)
subroutine, public sternheimer_unset_kxc(this)
subroutine, public sternheimer_end(this)
subroutine, public sternheimer_build_kxc(this, namespace, mesh, st, xc)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, ks, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
character(len=80) function, public str_center(s_in, l_in)
puts space around string, so that it is centered
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_t), public unit_ppm
Parts per million.
type(unit_system_t), public units_out
type(unit_t), public unit_susc_ppm_cgs
Some magnetic stuff.
type(unit_system_t), public units_inp
the units systems for reading and writing
type(unit_t), public unit_one
some special units required for particular quantities
This module is intended to contain simple general-purpose utility functions and procedures.
subroutine, public output_tensor(tensor, ndim, unit, write_average, iunit, namespace)
character pure function, public index2axis(idir)
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
class to tell whether a point is inside or outside
Class describing the electron system.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Container class for lists of system_oct_m::system_t.
The states_elec_t class contains all electronic wave functions.