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.
205 if (abs(sys%ks%xc%kernel_lrc_alpha) >
m_epsilon) em_vars%lrc_kernel = .
true.
207 if (em_vars%lrc_kernel .and. sys%space%periodic_dim < sys%space%dim)
then
208 message(1) =
'The use of the LRC kernel for non-periodic dimensions makes no sense.'
217 is_complex = complex_response)
220 message(1) =
"Previous gs calculation is required."
229 message(1) =
'Info: Using real wavefunctions.'
231 message(1) =
'Info: Using complex wavefunctions.'
236 message(1) =
'Info: Setting up Hamiltonian for linear response'
238 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
240 use_kdotp = sys%space%is_periodic() .and. .not. em_vars%force_no_kdotp
244 message(1) =
"em_resp with kdotp can only be used with semiconducting smearing"
250 message(1) =
"Reading kdotp wavefunctions for periodic directions."
255 message(1) =
"Unable to read kdotp wavefunctions."
256 message(2) =
"Previous kdotp calculation required."
260 do idir = 1, sys%space%periodic_dim
261 call lr_init(kdotp_lr(idir, 1))
262 call lr_allocate(kdotp_lr(idir, 1), sys%st, sys%gr, allocate_rho = .false.)
269 call states_elec_load(kdotp_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, ierr, &
270 lr=kdotp_lr(idir, 1))
275 message(1) =
"Could not load kdotp wavefunctions from '"//trim(
wfs_tag_sigma(sys%namespace, str_tmp, 1))//
"'"
276 message(2) =
"Previous kdotp calculation required."
285 if (em_vars%calc_hyperpol) em_vars%nfactor = 3
288 if (em_vars%calc_hyperpol .or. any(abs(em_vars%omega(1:em_vars%nomega)) >
m_epsilon))
then
296 if (em_vars%calc_hyperpol .and. use_kdotp)
then
300 call pert2_none%setup_dir(1)
301 safe_allocate(kdotp_em_lr2(1:sys%space%periodic_dim, 1:sys%space%dim, 1:em_vars%nsigma, 1:em_vars%nfactor))
302 do ifactor = 1, em_vars%nfactor
303 do sigma = 1, em_vars%nsigma
304 do idir = 1, sys%space%periodic_dim
305 do idir2 = 1, sys%space%dim
306 call lr_init(kdotp_em_lr2(idir, idir2, sigma, ifactor))
307 call lr_allocate(kdotp_em_lr2(idir, idir2, sigma, ifactor), sys%st, sys%gr, allocate_rho = .false.)
312 call sternheimer_init(sh2, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
313 complex_response, set_ham_var = 0, set_last_occ_response = .false.)
314 call sternheimer_init(sh_kdotp, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
315 complex_response, set_ham_var = 0, set_last_occ_response = .
true.)
316 em_vars%occ_response = .
true.
317 safe_allocate(dl_eig(1:sys%st%nst, 1:sys%st%nik, 1:sys%space%periodic_dim))
322 if (em_vars%calc_magnetooptics)
then
323 if (em_vars%calc_hyperpol .and. use_kdotp)
then
324 message(1) =
"Hyperpolarizability and magnetooptics with kdotp are not compatible."
325 message(2) =
"Only calculation of hyperpolarizability will be performed."
327 em_vars%calc_magnetooptics = .false.
330 em_vars%freq_factor(1) =
m_one
331 em_vars%freq_factor(2) = -
m_one
335 magnetic_pert = .false.
336 select type(ptr => em_vars%perturbation)
339 if (use_kdotp)
call messages_experimental(
"Magnetic perturbation for periodic systems", namespace=sys%namespace)
340 magnetic_pert = .
true.
343 if (em_vars%calc_magnetooptics .or. magnetic_pert)
then
344 em_vars%occ_response = .false.
348 call pert2_none%setup_dir(1)
350 safe_allocate(k2_lr(1:sys%space%dim, 1:sys%space%dim, 1))
351 safe_allocate(kb_lr(1:sys%space%dim, 1:sys%space%dim, 1))
352 do idir = 1, sys%space%dim
353 do idir2 = 1, sys%space%dim
354 call lr_init(kb_lr(idir, idir2, 1))
355 call lr_allocate(kb_lr(idir, idir2, 1), sys%st, sys%gr, allocate_rho = .false.)
356 if (idir2 <= idir)
then
357 call lr_init(k2_lr(idir, idir2, 1))
358 call lr_allocate(k2_lr(idir, idir2, 1), sys%st, sys%gr, allocate_rho = .false.)
363 if (sys%space%periodic_dim < sys%space%dim)
then
364 if (magnetic_pert)
then
365 message(1) =
"All directions should be periodic for magnetic perturbations with kdotp."
367 message(1) =
"All directions should be periodic for magnetooptics with kdotp."
371 if (.not. complex_response)
then
372 do idir = 1, sys%space%dim
376 do idir = 1, sys%space%dim
380 call sternheimer_init(sh_kmo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
381 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
385 safe_allocate(em_vars%lr(1:sys%space%dim, 1:em_vars%nsigma, 1:em_vars%nfactor))
386 do ifactor = 1, em_vars%nfactor
387 call born_charges_init(em_vars%Born_charges(ifactor), sys%namespace, sys%ions%natoms, &
388 sys%st%val_charge, sys%st%qtot, sys%space%dim)
391 if (magnetic_pert .and. sys%st%d%nspin == 1 .and.
states_are_real(sys%st))
then
393 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
394 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
397 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
398 complex_response, set_last_occ_response = em_vars%occ_response)
404 message(1) =
"Only the G = G'= 0 term of the LRC kernel is taken into account."
415 do ifactor = 1, em_vars%nfactor
416 do idir = 1, sys%space%dim
417 do sigma = 1, em_vars%nsigma
418 call lr_init(em_vars%lr(idir, sigma, ifactor))
419 call lr_allocate(em_vars%lr(idir, sigma, ifactor), sys%st, sys%gr, allocate_rho = allocate_rho_em)
424 select type(ptr=> em_vars%perturbation)
428 em_vars%kpt_output = .false.
430 if (.not. use_kdotp .or. sys%st%nik == 1) em_vars%kpt_output = .false.
432 if (em_vars%kpt_output)
then
433 safe_allocate(em_vars%alpha_k(1:sys%space%dim, 1:sys%space%dim, 1:em_vars%nfactor, 1:sys%st%nik))
436 if (em_vars%calc_magnetooptics)
then
437 if (em_vars%magnetooptics_nohvar)
then
438 call sternheimer_init(sh_mo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
439 complex_response, set_ham_var = 0, set_last_occ_response = em_vars%occ_response)
441 call sternheimer_init(sh_mo, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
442 complex_response, set_last_occ_response = em_vars%occ_response)
447 safe_allocate(b_lr(1:sys%space%dim, 1))
448 do idir = 1, sys%space%dim
450 call lr_allocate(b_lr(idir, 1), sys%st, sys%gr, allocate_rho = allocate_rho_mo)
454 if (em_vars%kpt_output)
then
455 safe_allocate(em_vars%alpha_be_k(1:sys%space%dim, 1:sys%space%dim, 1:sys%space%dim, 1:sys%st%nik))
458 if (sys%kpoints%use_time_reversal .and. sys%kpoints%full%npoints > 1) nfactor_ke = em_vars%nfactor
459 safe_allocate(ke_lr(1:sys%space%dim, 1:sys%space%dim, 1:em_vars%nsigma, 1:nfactor_ke))
460 do idir = 1, sys%space%dim
461 do idir2 = 1, sys%space%dim
462 do sigma = 1, em_vars%nsigma
463 do ifactor = 1, nfactor_ke
464 call lr_init(ke_lr(idir, idir2, sigma, ifactor))
465 call lr_allocate(ke_lr(idir, idir2, sigma, ifactor), sys%st, sys%gr, allocate_rho = .false.)
477 do iomega = 1, em_vars%nomega
479 em_vars%ok(1:3) = .
true.
481 do ifactor = 1, em_vars%nfactor
482 frequency = em_vars%freq_factor(ifactor)*em_vars%omega(iomega)
483 zfrequency_eta = frequency +
m_zi * em_vars%eta
484 if (em_vars%calc_magnetooptics .and. ifactor == 2) zfrequency_eta = frequency -
m_zi * em_vars%eta
485 dfrequency_eta = real(zfrequency_eta, real64)
487 if (abs(frequency) <
m_epsilon .and. em_vars%calc_magnetooptics .and. use_kdotp)
then
488 message(1) =
"Magnetooptical response with kdotp requires non-zero frequency."
496 have_to_calculate = .
true.
501 if (iomega > 1 .and. abs(em_vars%freq_factor(ifactor)) <=
m_epsilon) have_to_calculate = .false.
503 if (ifactor > 1 .and. (.not. em_vars%calc_magnetooptics))
then
506 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
509 do idir = 1, sys%space%dim
510 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, ifactor - 1), em_vars%lr(idir, 1, ifactor))
511 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, ifactor - 1), em_vars%lr(idir, 2, ifactor))
513 if (em_vars%calc_hyperpol .and. use_kdotp)
then
514 do idir2 = 1, sys%space%periodic_dim
515 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, ifactor - 1), &
516 kdotp_em_lr2(idir, idir2, 1, ifactor))
517 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, ifactor - 1), &
518 kdotp_em_lr2(idir, idir2, 2, ifactor))
523 have_to_calculate = .false.
528 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
531 do idir = 1, sys%space%dim
532 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, ifactor - 1), em_vars%lr(idir, 2, ifactor))
533 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, ifactor - 1), em_vars%lr(idir, 1, ifactor))
535 if (em_vars%calc_hyperpol .and. use_kdotp)
then
536 do idir2 = 1, sys%space%periodic_dim
537 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, ifactor - 1), &
538 kdotp_em_lr2(idir, idir2, 2, ifactor))
539 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, ifactor - 1), &
540 kdotp_em_lr2(idir, idir2, 1, ifactor))
545 have_to_calculate = .false.
551 if (iomega > 1 .and. ifactor == 1 .and. (.not. em_vars%calc_magnetooptics))
then
554 if (have_to_calculate .and. abs(frequency - last_omega) <
m_epsilon)
then
556 do idir = 1, sys%space%dim
557 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, em_vars%nfactor), em_vars%lr(idir, 1, 1))
558 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, em_vars%nfactor), em_vars%lr(idir, 2, 1))
560 if (em_vars%calc_hyperpol .and. use_kdotp)
then
561 do idir2 = 1, sys%space%periodic_dim
562 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, em_vars%nfactor), &
563 kdotp_em_lr2(idir, idir2, 1, 1))
564 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, em_vars%nfactor), &
565 kdotp_em_lr2(idir, idir2, 2, 1))
570 have_to_calculate = .false.
575 if (have_to_calculate .and. abs(frequency + last_omega) <
m_epsilon)
then
577 do idir = 1, sys%space%dim
578 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 1, em_vars%nfactor), em_vars%lr(idir, 2, 1))
579 call lr_copy(sys%st, sys%gr, em_vars%lr(idir, 2, em_vars%nfactor), em_vars%lr(idir, 1, 1))
581 if (em_vars%calc_hyperpol .and. use_kdotp)
then
582 do idir2 = 1, sys%space%periodic_dim
583 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 1, em_vars%nfactor), &
584 kdotp_em_lr2(idir, idir2, 2, 1))
585 call lr_copy(sys%st, sys%gr, kdotp_em_lr2(idir, idir2, 2, em_vars%nfactor), &
586 kdotp_em_lr2(idir, idir2, 1, 1))
591 have_to_calculate = .false.
597 if (have_to_calculate)
then
599 exact_freq(:) = .false.
602 call drun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
605 call zrun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
611 if (.not. have_to_calculate) cycle
614 call dcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
617 call zcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
629 last_omega = em_vars%freq_factor(em_vars%nfactor) * em_vars%omega(iomega)
633 do idir = 1, sys%space%dim
634 do sigma = 1, em_vars%nsigma
635 do ifactor = 1, em_vars%nfactor
636 call lr_dealloc(em_vars%lr(idir, sigma, ifactor))
642 deallocate(em_vars%perturbation)
645 do idir = 1, sys%space%periodic_dim
650 if (em_vars%calc_hyperpol .and. use_kdotp)
then
653 safe_deallocate_p(pert_kdotp)
654 safe_deallocate_p(pert2_none)
655 do idir = 1, sys%space%periodic_dim
656 do idir2 = 1, sys%space%periodic_dim
657 do sigma = 1, em_vars%nsigma
658 do ifactor = 1, em_vars%nfactor
659 call lr_dealloc(kdotp_em_lr2(idir, idir2, sigma, ifactor))
664 safe_deallocate_a(kdotp_em_lr2)
665 safe_deallocate_a(dl_eig)
668 if (em_vars%kpt_output)
then
669 safe_deallocate_a(em_vars%alpha_k)
672 if (em_vars%calc_magnetooptics .or. magnetic_pert)
then
674 safe_deallocate_p(pert2_none)
676 do idir = 1, sys%space%dim
677 do idir2 = 1, sys%space%dim
679 if (idir2 <= idir)
call lr_dealloc(k2_lr(idir, idir2, 1))
682 safe_deallocate_a(k2_lr)
683 safe_deallocate_a(kb_lr)
687 if (em_vars%calc_magnetooptics)
then
690 do idir = 1, sys%space%dim
693 safe_deallocate_a(b_lr)
696 do idir = 1, sys%space%dim
697 do idir2 = 1, sys%space%dim
698 do sigma = 1, em_vars%nsigma
699 do ifactor = 1, nfactor_ke
700 call lr_dealloc(ke_lr(idir, idir2, sigma, ifactor))
705 safe_deallocate_a(ke_lr)
706 if (em_vars%kpt_output)
then
707 safe_deallocate_a(em_vars%alpha_be_k)
710 safe_deallocate_p(pert_b)
714 safe_deallocate_a(em_vars%omega)
715 safe_deallocate_a(em_vars%lr)
716 do ifactor = 1, em_vars%nfactor
728 integer :: nrow, irow, nfreqs_in_row, ifreq, istep, perturb_type
729 real(real64) :: omega_ini, omega_fin, domega
760 if (
parse_block(sys%namespace,
'EMFreqs', blk) == 0)
then
768 if (nfreqs_in_row < 1)
then
769 message(1) =
"EMFreqs: invalid number of frequencies."
772 em_vars%nomega = em_vars%nomega + nfreqs_in_row
775 safe_allocate(em_vars%omega(1:em_vars%nomega))
782 if (nfreqs_in_row > 1)
then
784 domega = (omega_fin - omega_ini)/(nfreqs_in_row -
m_one)
785 do istep = 0, nfreqs_in_row-1
788 ifreq = ifreq + nfreqs_in_row
808 if (freq_sort)
call sort(em_vars%omega)
813 safe_allocate(em_vars%omega(1:em_vars%nomega))
831 message(1) =
"EMEta cannot be negative."
836 em_vars%calc_hyperpol = .false.
837 em_vars%freq_factor(1:3) =
m_one
838 em_vars%calc_magnetooptics = .false.
839 em_vars%magnetooptics_nohvar = .
true.
840 em_vars%kpt_output = .false.
856 call parse_variable(sys%namespace,
'EMPerturbationType', perturbation_electric, perturb_type)
859 select case(perturb_type)
860 case(perturbation_electric)
870 select type(ptr=>em_vars%perturbation)
881 call parse_variable(sys%namespace,
'EMCalcRotatoryResponse', .false., em_vars%calc_rotatory)
895 if (
parse_block(sys%namespace,
'EMHyperpol', blk) == 0)
then
902 if (abs(sum(em_vars%freq_factor(1:3))) >
m_epsilon)
then
903 message(1) =
"Frequency factors specified by EMHyperpol must sum to zero."
907 em_vars%calc_hyperpol = .
true.
917 call parse_variable(sys%namespace,
'EMCalcMagnetooptics', .false., em_vars%calc_magnetooptics)
927 call parse_variable(sys%namespace,
'EMMagnetoopticsNoHVar', .
true., em_vars%magnetooptics_nohvar)
938 call parse_variable(sys%namespace,
'EMKPointOutput', .false., em_vars%kpt_output)
954 call parse_variable(sys%namespace,
'EMForceNoKdotP', .false., em_vars%force_no_kdotp)
964 call parse_variable(sys%namespace,
'EMCalcBornCharges', .false., em_vars%calc_Born)
965 if (em_vars%calc_Born)
call messages_experimental(
"Calculation of Born effective charges", namespace=sys%namespace)
978 call parse_variable(sys%namespace,
'EMOccupiedResponse', .false., em_vars%occ_response)
980 message(1) =
"EMOccupiedResponse cannot be used if there are partial occupations."
994 call parse_variable(sys%namespace,
'EMWavefunctionsFromScratch', .false., em_vars%wfns_from_scratch)
1006 call em_vars%perturbation%info()
1007 select type(ptr=>em_vars%perturbation)
1009 if (em_vars%calc_hyperpol)
then
1019 message(1) =
'Wavefunctions type: Real'
1021 message(1) =
'Wavefunctions type: Complex'
1025 write(
message(1),
'(a,i3,a)')
'Calculating response for ', em_vars%nomega,
' frequencies.'
1037#include "em_resp_inc.F90"
1040#include "complex.F90"
1041#include "em_resp_inc.F90"
1048 subroutine em_resp_output(st, namespace, space, gr, hm, ions, outp, sh, em_vars, iomega, ifactor)
1051 class(
space_t),
intent(in) :: space
1052 type(
grid_t),
intent(in) :: gr
1054 type(
ions_t),
intent(in) :: ions
1057 type(
em_resp_t),
intent(inout) :: em_vars
1058 integer,
intent(in) :: iomega
1059 integer,
intent(in) :: ifactor
1061 integer :: iunit, idir
1062 character(len=80) :: dirname, str_tmp
1063 logical :: use_kdotp
1064 complex(real64) :: epsilon(space%dim, space%dim)
1068 use_kdotp = space%is_periodic() .and. .not. em_vars%force_no_kdotp
1072 write(dirname,
'(a, a)')
em_resp_dir//
'freq_', trim(str_tmp)
1073 call io_mkdir(trim(dirname), namespace)
1076 iunit =
io_open(trim(dirname)//
'/photon_coord_q', namespace, action=
'write')
1078 write(iunit,
'(a)')
' Re Im'
1079 do idir = 1, space%dim
1088 select type(ptr=>em_vars%perturbation)
1090 if ((.not. em_vars%calc_magnetooptics) .or. ifactor == 1)
then
1092 if (em_vars%calc_Born)
then
1093 call born_output_charges(em_vars%born_charges(ifactor), ions%atom, ions%charge, ions%natoms, &
1094 namespace, space%dim, dirname, write_real = em_vars%eta <
m_epsilon)
1097 if (space%periodic_dim == space%dim)
then
1101 if ((.not. space%is_periodic() .or. em_vars%force_no_kdotp) .and. em_vars%calc_rotatory)
then
1126 iunit =
io_open(trim(dirname)//
'/eta', namespace, action=
'write')
1140 integer,
intent(in) :: out_file
1142 character(len=80) :: header_string
1143 integer :: ii, idir, kdir
1150 write(out_file,
'(a1, a20)', advance =
'no')
'#',
str_center(
"Energy", 20)
1151 write(out_file,
'(a20)', advance =
'no')
str_center(
"(1/3)*Tr[sigma]", 20)
1152 write(out_file,
'(a20)', advance =
'no')
str_center(
"Anisotropy[sigma]", 20)
1154 do idir = 1, space%dim
1155 do kdir = 1, space%dim
1156 write(header_string,
'(a6,i1,a1,i1,a1)')
'sigma(', idir,
',', kdir,
')'
1157 write(out_file,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1163 do ii = 1, 2 + space%dim**2
1174 real(real64) :: cross(space%dim, space%dim), crossp(space%dim, space%dim)
1175 real(real64) :: cross_sum, crossp_sum, anisotropy
1176 integer :: idir, idir2
1182 iunit =
io_open(trim(dirname)//
'/alpha', namespace, action=
'write')
1184 if (.not. em_vars%ok(ifactor))
write(iunit,
'(a)')
"# WARNING: not converged"
1187 call output_tensor(real(em_vars%alpha(:, :, ifactor), real64), space%dim,
units_out%polarizability, iunit=iunit)
1193 cross(1:space%dim, 1:space%dim) = aimag(em_vars%alpha(1:space%dim, 1:space%dim, ifactor)) * &
1194 em_vars%freq_factor(ifactor) * em_vars%omega(iomega) * (
m_four *
m_pi /
p_c)
1196 do idir = 1, space%dim
1197 do idir2 = 1, space%dim
1202 iunit =
io_open(trim(dirname)//
'/cross_section', namespace, action=
'write')
1203 if (.not. em_vars%ok(ifactor))
write(iunit,
'(a)')
"# WARNING: not converged"
1205 crossp(1:space%dim, 1:space%dim) = matmul(cross(1:space%dim, 1:space%dim), cross(1:space%dim, 1:space%dim))
1209 do idir = 1, space%dim
1210 cross_sum = cross_sum + cross(idir, idir)
1211 crossp_sum = crossp_sum + crossp(idir, idir)
1214 anisotropy = crossp_sum -
m_third * cross_sum**2
1217 write(iunit,
'(3e20.8)', advance =
'no') &
1220 do idir = 1, space%dim
1221 do idir2 = 1, space%dim
1222 write(iunit,
'(e20.8)', advance =
'no') cross(idir, idir2)
1225 write(iunit,
'(a)', advance =
'yes')
1237 integer :: idir, idir1, ik
1238 character(len=80) :: header_string
1239 complex(real64),
allocatable :: epsilon_k(:, :, :)
1245 iunit =
io_open(trim(dirname)//
'/epsilon', namespace, action=
'write')
1246 if (.not. em_vars%ok(ifactor))
write(iunit,
'(a)')
"# WARNING: not converged"
1248 epsilon(1:space%dim, 1:space%dim) = &
1249 4 *
m_pi * em_vars%alpha(1:space%dim, 1:space%dim, ifactor) / ions%latt%rcell_volume
1250 do idir = 1, space%dim
1251 epsilon(idir, idir) = epsilon(idir, idir) +
m_one
1254 write(iunit,
'(a)')
'# Real part of dielectric constant'
1255 call output_tensor(real(epsilon(1:space%dim, 1:space%dim), real64), space%dim,
unit_one, iunit=iunit)
1257 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1260 if (em_vars%lrc_kernel)
then
1262 write(iunit,
'(a)')
'# Without G = G'' = 0 term of the LRC kernel'
1264 epsilon(1:space%dim, 1:space%dim) = &
1265 4 *
m_pi * em_vars%alpha0(1:space%dim, 1:space%dim, ifactor) / ions%latt%rcell_volume
1266 do idir = 1, space%dim
1267 epsilon(idir, idir) = epsilon(idir, idir) +
m_one
1270 write(iunit,
'(a)')
'# Real part of dielectric constant'
1271 call output_tensor(real(epsilon(1:space%dim, 1:space%dim), real64), space%dim,
unit_one, iunit=iunit)
1273 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1279 if (em_vars%kpt_output)
then
1280 safe_allocate(epsilon_k(1:space%dim, 1:space%dim, 1:hm%kpoints%reduced%npoints))
1281 do ik = 1, hm%kpoints%reduced%npoints
1282 do idir = 1, space%dim
1283 do idir1 = 1, space%dim
1284 epsilon_k(idir, idir1, ik) =
m_four *
m_pi * em_vars%alpha_k(idir, idir1, ifactor, ik) / ions%latt%rcell_volume
1288 iunit =
io_open(trim(dirname)//
'/epsilon_k_re', namespace, action=
'write')
1290 write(iunit,
'(a)')
'# Real part of dielectric constant'
1291 write(iunit,
'(a10)', advance =
'no')
'# index '
1292 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1293 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1294 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1295 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1297 do idir = 1, space%dim
1298 do idir1 = 1, space%dim
1299 write(header_string,
'(a7,i1,a1,i1,a1)')
'Re eps(', idir,
',', idir1,
')'
1300 write(iunit,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1305 do ik = 1, hm%kpoints%reduced%npoints
1306 write(iunit,
'(i8)', advance =
'no') ik
1307 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1308 do idir = 1, space%dim
1309 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1311 do idir = 1, space%dim
1312 do idir1 = 1, space%dim
1313 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_k(idir, idir1, ik), real64)
1320 iunit =
io_open(trim(dirname)//
'/epsilon_k_im', namespace, action=
'write')
1322 write(iunit,
'(a)')
'# Imaginary part of dielectric constant'
1323 write(iunit,
'(a10)', advance =
'no')
'# index '
1324 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1325 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1326 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1327 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1329 do idir = 1, space%dim
1330 do idir1 = 1, space%dim
1331 write(header_string,
'(a7,i1,a1,i1,a1)')
'Im eps(', idir,
',', idir1,
')'
1332 write(iunit,
'(a20)', advance =
'no')
str_center(trim(header_string), 20)
1337 do ik = 1, hm%kpoints%reduced%npoints
1338 write(iunit,
'(i8)', advance =
'no') ik
1339 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1340 do idir = 1, space%dim
1341 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1343 do idir = 1, space%dim
1344 do idir1 = 1, space%dim
1345 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_k(idir, idir1, ik))
1351 safe_deallocate_a(epsilon_k)
1361 character(len=80) :: dirname1
1367 select type(ptr=>em_vars%perturbation)
1370 call io_mkdir(trim(dirname1), namespace)
1371 iunit =
io_open(trim(dirname1)//
'/susceptibility', namespace, action=
'write')
1373 iunit =
io_open(trim(dirname)//
'/susceptibility', namespace, action=
'write')
1376 if (.not. em_vars%ok(ifactor))
write(iunit,
'(a)')
"# WARNING: not converged"
1380 if (.not. use_kdotp)
then
1381 write(iunit,
'(2a)')
'# Paramagnetic contribution to the susceptibility tensor [ppm a.u.]'
1383 write(iunit,
'(1x)')
1385 write(iunit,
'(2a)')
'# Diamagnetic contribution to the susceptibility tensor [ppm a.u.]'
1387 write(iunit,
'(1x)')
1390 write(iunit,
'(2a)')
'# Total susceptibility tensor [ppm a.u.]'
1391 call output_tensor(real(em_vars%chi_para(:, :) + em_vars%chi_dia(:,:), real64) , &
1393 write(iunit,
'(1x)')
1397 if (.not. use_kdotp)
then
1398 write(iunit,
'(2a)')
'# Paramagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1400 write(iunit,
'(1x)')
1402 write(iunit,
'(2a)')
'# Diamagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1404 write(iunit,
'(1x)')
1407 write(iunit,
'(2a)')
'# Total susceptibility tensor [ppm cgs / mol]'
1408 call output_tensor(real(em_vars%chi_para(:, :) + em_vars%chi_dia(:,:), real64), &
1410 write(iunit,
'(1x)')
1414 write(iunit,
'(1a)')
'# Magnetization [ppm a.u.]'
1427 integer :: idir, isigma
1431 do idir = 1, space%dim
1434 if (space%dim == 3 .and. outp%what(option__output__elf))
then
1435 if (em_vars%nsigma == 1)
then
1436 call zlr_calc_elf(st, space, gr, hm%kpoints, em_vars%lr(idir, 1, ifactor))
1438 call zlr_calc_elf(st, space, gr, hm%kpoints, em_vars%lr(idir, 1, ifactor), em_vars%lr(idir, 2, ifactor))
1441 do isigma = 1, em_vars%nsigma
1442 call zoutput_lr(outp, namespace, space, dirname, st, gr, em_vars%lr(idir, isigma, ifactor), idir, isigma, ions, &
1447 if (space%dim == 3 .and. outp%what(option__output__elf))
then
1448 if (em_vars%nsigma == 1)
then
1449 call dlr_calc_elf(st, space, gr, hm%kpoints, em_vars%lr(idir, 1, ifactor))
1451 call dlr_calc_elf(st, space, gr, hm%kpoints, em_vars%lr(idir, 1, ifactor), em_vars%lr(idir, 2, ifactor))
1455 do isigma = 1, em_vars%nsigma
1456 call doutput_lr(outp, namespace, space, dirname, st, gr, em_vars%lr(idir, isigma, ifactor), idir, isigma, ions, &
1476 complex(real64) :: dic
1477 complex(real64),
allocatable :: psi(:, :, :, :)
1483 message(1) =
"Info: Calculating rotatory response."
1488 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))
1493 do idir = 1, space%dim
1494 call angular_momentum%setup_dir(idir)
1496 + angular_momentum%zexpectation_value(namespace, space, gr, hm, st, psi, &
1497 em_vars%lr(idir, 1, ifactor)%zdl_psi) &
1498 + angular_momentum%zexpectation_value(namespace, space, gr, hm, st, &
1499 em_vars%lr(idir, 2, ifactor)%zdl_psi, psi)
1502 safe_deallocate_a(psi)
1504 safe_deallocate_p(angular_momentum)
1510 iunit =
io_open(trim(dirname)//
'/rotatory_strength', namespace, action=
'write')
1513 write(iunit,
'(a1,a20,a20,a20)')
'#',
str_center(
"Energy", 20),
str_center(
"R", 20),
str_center(
"Re[beta]", 20)
1519 if (abs(em_vars%omega(iomega)) >
m_epsilon) ff = real(dic, real64) /(
m_three*em_vars%omega(iomega))
1535 complex(real64) :: epsilon_m(4), diff(4), eps_mk(space%dim)
1542 assert(space%dim == 3)
1545 do idir = 1, space%dim
1549 diff(4) = (diff(1) + diff(2) + diff(3)) /
m_three
1551 iunit =
io_open(trim(dirname)//
'/alpha_mo', namespace, action=
'write')
1553 if (.not. em_vars%ok(ifactor))
write(iunit,
'(a)')
"# WARNING: not converged"
1555 write(iunit,
'(a1, a25)', advance =
'no')
'#',
str_center(
" ", 25)
1556 write(iunit,
'(a20)', advance =
'no')
str_center(
" yz,x = -zy,x", 20)
1557 write(iunit,
'(a20)', advance =
'no')
str_center(
" zx,y = -xz,y", 20)
1558 write(iunit,
'(a20)', advance =
'no')
str_center(
" xy,z = -yx,z", 20)
1559 write(iunit,
'(a20)', advance =
'no')
str_center(
" Average", 20)
1562 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re alpha [a.u.]", 25)
1563 do idir = 1, space%dim + 1
1564 write(iunit,
'(e20.8)', advance =
'no') real(diff(idir), real64)
1568 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im alpha [a.u.]", 25)
1569 do idir = 1, space%dim + 1
1570 write(iunit,
'(e20.8)', advance =
'no') aimag(diff(idir))
1574 if (space%is_periodic())
then
1576 assert(space%periodic_dim == 3)
1578 do idir = 1, space%dim
1579 epsilon_m(idir) = 4 *
m_pi * diff(idir) / ions%latt%rcell_volume
1581 epsilon_m(4) = 4 *
m_pi * diff(4) / ions%latt%rcell_volume
1583 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re epsilon (B = 1 a.u.)", 25)
1584 do idir = 1, space%dim + 1
1585 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_m(idir), real64)
1589 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im epsilon (B = 1 a.u.)", 25)
1590 do idir = 1, space%dim + 1
1591 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_m(idir))
1595 if (em_vars%lrc_kernel)
then
1597 write(iunit,
'(a)')
'# Without the G = G'' = 0 term of the LRC kernel'
1601 do idir = 1, space%dim
1605 epsilon_m(idir) = 4 *
m_pi * diff(idir) / ions%latt%rcell_volume
1607 diff(4) = (diff(1) + diff(2) + diff(3)) /
m_three
1608 epsilon_m(4) = 4 *
m_pi * diff(4) / ions%latt%rcell_volume
1610 write(iunit,
'(a1, a25)', advance =
'no')
'#',
str_center(
" ", 25)
1611 write(iunit,
'(a20)', advance =
'no')
str_center(
" yz,x = -zy,x", 20)
1612 write(iunit,
'(a20)', advance =
'no')
str_center(
" zx,y = -xz,y", 20)
1613 write(iunit,
'(a20)', advance =
'no')
str_center(
" xy,z = -yx,z", 20)
1614 write(iunit,
'(a20)', advance =
'no')
str_center(
" Average", 20)
1617 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re alpha [a.u.]", 25)
1618 do idir = 1, space%dim + 1
1619 write(iunit,
'(e20.8)', advance =
'no') real(diff(idir), real64)
1623 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im alpha [a.u.]", 25)
1624 do idir = 1, space%dim + 1
1625 write(iunit,
'(e20.8)', advance =
'no') aimag(diff(idir))
1629 write(iunit,
'(a25)', advance =
'no')
str_center(
"Re epsilon (B = 1 a.u.)", 25)
1630 do idir = 1, space%dim + 1
1631 write(iunit,
'(e20.8)', advance =
'no') real(epsilon_m(idir), real64)
1635 write(iunit,
'(a25)', advance =
'no')
str_center(
"Im epsilon (B = 1 a.u.)", 25)
1636 do idir = 1, space%dim + 1
1637 write(iunit,
'(e20.8)', advance =
'no') aimag(epsilon_m(idir))
1644 if (space%is_periodic() .and. em_vars%kpt_output)
then
1645 iunit =
io_open(trim(dirname)//
'/epsilon_mo_k', namespace, action=
'write')
1647 write(iunit,
'(a)')
'# Contribution to dielectric tensor for B = 1 a.u.'
1648 write(iunit,
'(a10)', advance =
'no')
'# index '
1649 write(iunit,
'(a20)', advance =
'no')
str_center(
"weight", 20)
1650 write(iunit,
'(a20)', advance =
'no')
str_center(
"kx", 20)
1651 write(iunit,
'(a20)', advance =
'no')
str_center(
"ky", 20)
1652 write(iunit,
'(a20)', advance =
'no')
str_center(
"kz", 20)
1653 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_yz,x", 20)
1654 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_zx,y", 20)
1655 write(iunit,
'(a20)', advance =
'no')
str_center(
"Re eps_xy,z", 20)
1656 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_yz,x", 20)
1657 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_zx,y", 20)
1658 write(iunit,
'(a20)', advance =
'no')
str_center(
"Im eps_xy,z", 20)
1661 do ik = 1, hm%kpoints%reduced%npoints
1662 write(iunit,
'(i8)', advance =
'no') ik
1663 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%weight(ik)
1664 do idir = 1, space%dim
1666 em_vars%alpha_be_k(
magn_dir(idir, 2),
magn_dir(idir, 1), idir, ik)) / ions%latt%rcell_volume
1669 do idir = 1, space%dim
1670 write(iunit,
'(e20.8)', advance =
'no') hm%kpoints%reduced%red_point(idir, ik)
1672 do idir = 1, space%dim
1673 write(iunit,
'(e20.8)', advance =
'no') real(eps_mk(idir), real64)
1675 do idir = 1, space%dim
1676 write(iunit,
'(e20.8)', advance =
'no') aimag(eps_mk(idir))
1693 class(
box_t),
intent(in) :: box
1694 complex(real64),
intent(in) :: beta(:, :, :)
1695 real(real64),
intent(in) :: freq_factor(:)
1696 logical,
intent(in) :: converged
1697 character(len=*),
intent(in) :: dirname
1700 complex(real64) :: bpar(1:box%dim), bper(1:box%dim), bk(1:box%dim)
1701 complex(real64) :: HRS_VV, HRS_HV
1702 integer :: ii, jj, kk, iunit
1709 iunit =
io_open(trim(dirname)//
'/beta', namespace, action=
'write')
1711 if (.not. converged)
write(iunit,
'(a)')
"# WARNING: not converged"
1713 write(iunit,
'(a,3(f4.1,a),2a)', advance=
'no')
'First hyperpolarizability tensor: beta(', &
1714 freq_factor(1),
', ', freq_factor(2),
', ', freq_factor(3),
') [', &
1722 write(iunit,
'(a,e20.8,e20.8)')
'beta '// &
1730 if (box%dim == 3)
then
1736 bpar(ii) = bpar(ii) + beta(ii, jj, jj) + beta(jj, ii, jj) + beta(jj, jj, ii)
1737 bper(ii) = bper(ii) +
m_two*beta(ii, jj, jj) -
m_three*beta(jj, ii, jj) +
m_two*beta(jj, jj, ii)
1745 bk(1:box%dim) =
m_three*
m_half*(bpar(1:box%dim) - bper(1:box%dim))
1748 write(iunit,
'(a, 2e20.8)')
'beta // '//
index2axis(ii), &
1756 write(iunit,
'(a, 2e20.8)')
'beta _L '//
index2axis(ii), &
1764 write(iunit,
'(a, 2e20.8)')
'beta k '//
index2axis(ii), &
1772 write(iunit,
'(a)')
'beta for liquid- or gas-phase hyper-Rayleigh scattering:'
1773 write(iunit,
'(a, 2e20.8)')
'VV polarization ', &
1776 write(iunit,
'(a, 2e20.8)')
'HV polarization ', &
1792 class(
box_t),
intent(in) :: box
1793 complex(real64),
intent(in) :: beta(:, :, :)
1794 complex(real64),
intent(out) :: HRS_VV, HRS_HV
1796 complex(real64) :: HRS_A, HRS_B, HRS_C, HRS_D, HRS_E
1797 complex(real64) :: HRS_B1, HRS_B2, HRS_C1, HRS_C2, HRS_C3, HRS_D1, HRS_D2, HRS_D3, HRS_E1, HRS_E2
1805 hrs_a = hrs_a + beta(ii,ii,ii)**2
1813 hrs_b = hrs_b + beta(ii,ii,ii) * (beta(ii,jj,jj) + beta(jj,ii,jj) + beta(jj,jj,ii))
1814 hrs_c = hrs_c + (beta(ii,ii,jj) + beta(ii,jj,ii) + beta(jj,ii,ii))**2
1819 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)) &
1820 + (beta(2,2,3) + beta(2,3,2) + beta(3,2,2)) * (beta(3,1,1) + beta(1,3,1) + beta(1,1,3)) &
1821 + (beta(3,3,1) + beta(3,1,3) + beta(1,3,3)) * (beta(1,2,2) + beta(2,1,2) + beta(2,2,1))
1823 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
1825 hrs_vv = (
m_one / 7.0_real64) * hrs_a &
1826 + (
m_two / 35.0_real64) * hrs_b &
1827 + (
m_one / 35.0_real64) * hrs_c &
1828 + (
m_two / 105.0_real64) * hrs_d &
1829 + (
m_one / 105.0_real64) * hrs_e
1840 hrs_b1 = hrs_b1 + beta(ii,ii,ii) * beta(ii,jj,jj)
1841 hrs_b2 = hrs_b2 + beta(ii,ii,ii) * (beta(jj,ii,jj) + beta(jj,jj,ii))
1842 hrs_c1 = hrs_c1 + (beta(ii,ii,jj) + beta(ii,jj,ii))**2
1843 hrs_c2 = hrs_c2 + beta(jj,ii,ii) * (beta(ii,ii,jj) + beta(ii,jj,ii))
1844 hrs_c3 = hrs_c3 + beta(jj,ii,ii)**2
1849 hrs_d1 = (beta(1,1,2) + beta(1,2,1) + beta(2,1,1)) * (beta(3,2,3) + beta(3,3,2)) &
1850 + (beta(2,2,3) + beta(2,3,2) + beta(3,2,2)) * (beta(1,3,1) + beta(1,1,3)) &
1851 + (beta(3,3,1) + beta(3,1,3) + beta(1,3,3)) * (beta(2,1,2) + beta(2,2,1))
1852 hrs_d2 = (beta(1,1,2) + beta(1,2,1)) * beta(2,3,3) &
1853 + (beta(2,2,3) + beta(2,3,2)) * beta(3,1,1) &
1854 + (beta(3,3,1) + beta(3,1,3)) * beta(1,2,2)
1855 hrs_d3 = beta(2,1,1) * beta(2,3,3) &
1856 + beta(3,2,2) * beta(3,1,1) &
1857 + beta(1,3,3) * beta(1,2,2)
1859 hrs_e1 = (beta(1,2,3) + beta(1,3,2))**2 &
1860 + (beta(2,1,3) + beta(2,3,1))**2 &
1861 + (beta(3,1,2) + beta(3,2,1))**2
1863 hrs_e2 = (beta(1,2,3) + beta(1,3,2)) * (beta(2,1,3) + beta(2,3,1)) &
1864 + (beta(2,1,3) + beta(2,3,1)) * (beta(3,1,2) + beta(3,2,1)) &
1865 + (beta(3,1,2) + beta(3,2,1)) * (beta(1,2,3) + beta(1,3,2))
1867 hrs_hv = (
m_one / 35.0_real64) * hrs_a &
1868 + (
m_four / 105.0_real64) * hrs_b1 &
1869 - (
m_one / 35.0_real64) * hrs_b2 &
1870 + (
m_two / 105.0_real64) * hrs_c1 &
1871 - (
m_one / 35.0_real64) * hrs_c2 &
1872 + (
m_three / 35.0_real64) * hrs_c3 &
1873 - (
m_one / 105.0_real64) * hrs_d1 &
1874 - (
m_one / 105.0_real64) * hrs_d2 &
1875 + (
m_two / 35.0_real64) * hrs_d3 &
1876 + (
m_one / 35.0_real64) * hrs_e1 &
1877 - (
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)
subroutine, public dlr_calc_elf(st, space, gr, kpoints, lr, lr_m)
subroutine, public zlr_calc_elf(st, space, gr, kpoints, lr, lr_m)
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)
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)
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
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)
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
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 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
type(restart_data_t), dimension(restart_n_data_types) info
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
subroutine, public restart_open_dir(restart, dirname, ierr)
Change the restart directory to dirname, where "dirname" is a subdirectory of the base restart direct...
integer, parameter, public restart_type_load
subroutine, public restart_end(restart)
subroutine, public restart_close_dir(restart)
Change back to the base directory. To be called after restart_open_dir.
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, is_complex, packed)
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, 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)
logical function, public sternheimer_add_fxc(this)
subroutine, public sternheimer_unset_kxc(this)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
subroutine, public sternheimer_end(this)
subroutine, public sternheimer_build_kxc(this, namespace, mesh, st, xc)
logical function, public sternheimer_add_hartree(this)
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.