Octopus
em_resp.F90
Go to the documentation of this file.
1!! Copyright (C) 2004-2012 Xavier Andrade, Eugene S. Kadantsev (ekadants@mjs1.phy.queensu.ca), David Strubbe
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module em_resp_oct_m
23 use box_oct_m
24 use debug_oct_m
27 use forces_oct_m
28 use global_oct_m
29 use grid_oct_m
32 use io_oct_m
33 use ions_oct_m
34 use, intrinsic :: iso_fortran_env
35 use kdotp_oct_m
39 use loct_oct_m
40 use mesh_oct_m
43 use mpi_oct_m
47 use output_oct_m
48 use parser_oct_m
49 use pcm_oct_m
57 use smear_oct_m
58 use sort_oct_m
59 use space_oct_m
65 use string_oct_m
66 use unit_oct_m
68 use utils_oct_m
69 use v_ks_oct_m
70 use xc_oct_m
71
72 implicit none
73
74 private
75
76 public :: &
79
80 integer, parameter :: &
81 PERTURBATION_ELECTRIC = 1, &
84
85
86 type em_resp_t
87 private
88 class(perturbation_t), pointer :: perturbation
89
90 integer :: nsigma
92 integer :: nfactor
95 integer :: nomega
96
97 real(real64) :: eta
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)
113
114 complex(real64) :: chi_para(3, 3)
115 complex(real64) :: chi_dia (3, 3)
116 complex(real64) :: magn(3)
117
118 logical :: ok(1:3)
119 logical :: force_no_kdotp
120
121 logical :: calc_rotatory
122 logical :: calc_Born
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
132
133 end type em_resp_t
134
135contains
136
137 ! ---------------------------------------------------------
138 subroutine em_resp_run(system, from_scratch)
139 class(*), intent(inout) :: system
140 logical, intent(in) :: from_scratch
141
142 push_sub(em_resp_run)
143
144 select type (system)
145 class is (multisystem_basic_t)
146 message(1) = "CalculationMode = em_resp not implemented for multi-system calculations"
147 call messages_fatal(1, namespace=system%namespace)
148 type is (electrons_t)
149 call em_resp_run_legacy(system, from_scratch)
150 end select
151
152 pop_sub(em_resp_run)
153 end subroutine em_resp_run
154
155 ! ---------------------------------------------------------
156 subroutine em_resp_run_legacy(sys, fromScratch)
157 type(electrons_t), intent(inout) :: sys
158 logical, intent(in) :: fromScratch
159
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
168
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
180
182
183 if (sys%hm%pcm%run_pcm) then
184 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
185 end if
186
187 if (sys%kpoints%use_symmetries) then
188 call messages_experimental("em_resp with k-points symmetries", namespace=sys%namespace)
189 end if
191 if (sys%kpoints%reduced%npoints /= sys%kpoints%full%npoints) then
192 call messages_experimental('em_resp with reduced k-grid', namespace=sys%namespace)
193 end if
197 select type(ptr=>em_vars%perturbation)
199 if (any(abs(em_vars%omega(1:em_vars%nomega)) > m_epsilon)) then
200 call messages_not_implemented('Dynamical magnetic response', namespace=sys%namespace)
201 end if
202 end select
204 em_vars%lrc_kernel = .false.
205 if (abs(sys%ks%xc%lrc%alpha) > m_epsilon) em_vars%lrc_kernel = .true.
206
207 complex_wfs = states_are_complex(sys%st)
208 complex_response = (em_vars%eta > m_epsilon) .or. states_are_complex(sys%st)
209 call gs_restart%init(sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=sys%gr, exact=.true.)
210 if (ierr == 0) then
211 call states_elec_look_and_load(gs_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
212 sys%st%restart_fixed_occ, is_complex = complex_response)
213 call gs_restart%end()
214 else
215 message(1) = "Previous gs calculation is required."
216 call messages_fatal(1, namespace=sys%namespace)
217 end if
219 ! Use of ForceComplex will make this true after states_elec_look_and_load even if it was not before.
220 ! Otherwise, this line is a tautology.
221 complex_response = states_are_complex(sys%st)
223 if (states_are_real(sys%st)) then
224 message(1) = 'Info: Using real wavefunctions.'
225 else
226 message(1) = 'Info: Using complex wavefunctions.'
227 end if
228 call messages_info(1, namespace=sys%namespace)
229
230 ! setup Hamiltonian
231 message(1) = 'Info: Setting up Hamiltonian for linear response'
232 call messages_info(1, namespace=sys%namespace)
233 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
234
235 use_kdotp = sys%space%is_periodic() .and. .not. em_vars%force_no_kdotp
236
237 if (use_kdotp .and. .not. smear_is_semiconducting(sys%st%smear)) then
238 ! there needs to be a gap.
239 message(1) = "em_resp with kdotp can only be used with semiconducting smearing"
240 call messages_fatal(1, namespace=sys%namespace)
241 end if
242
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."
246 call messages_warning(2, namespace=sys%namespace)
247 end if
248
249 ! read kdotp wavefunctions if necessary
250 if (use_kdotp) then
251 message(1) = "Reading kdotp wavefunctions for periodic directions."
252 call messages_info(1, namespace=sys%namespace)
253
254 call kdotp_restart%init(sys%namespace, restart_kdotp, restart_type_load, sys%mc, ierr, mesh=sys%gr)
255 if (ierr /= 0) then
256 message(1) = "Unable to read kdotp wavefunctions."
257 message(2) = "Previous kdotp calculation required."
258 call messages_fatal(2, namespace=sys%namespace)
259 end if
260
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.)
264
265 ! load wavefunctions
266 str_tmp = kdotp_wfs_tag(idir)
267 ! 1 is the sigma index which is used in em_resp
268 call kdotp_restart%open_dir(wfs_tag_sigma(sys%namespace, str_tmp, 1), ierr)
269 if (ierr == 0) then
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))
272 end if
273 call kdotp_restart%close_dir()
274
275 if (ierr /= 0) then
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."
278 call messages_fatal(2, namespace=sys%namespace)
279 end if
280 end do
281
282 call kdotp_restart%end()
283 end if
284
285 em_vars%nfactor = 1
286 if (em_vars%calc_hyperpol) em_vars%nfactor = 3
287
288 ! in effect, nsigma = 1 only if hyperpol not being calculated, and the only frequency is zero
289 if (em_vars%calc_hyperpol .or. any(abs(em_vars%omega(1:em_vars%nomega)) > m_epsilon)) then
290 em_vars%nsigma = 2
291 ! positive and negative values of the frequency must be considered
292 else
293 em_vars%nsigma = 1
294 ! only considering positive values
295 end if
296
297 if (em_vars%calc_hyperpol .and. use_kdotp) then
298 pert_kdotp => perturbation_kdotp_t(sys%namespace, sys%ions)
299 pert2_none => perturbation_none_t(sys%namespace)
300 call messages_experimental("Second-order Sternheimer equation", namespace=sys%namespace)
301 call pert2_none%setup_dir(1) ! direction is irrelevant
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.)
309 end do
310 end do
311 end do
312 end do
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))
319 end if
320
321 ! Hyperpolarizability requires full corrections to wavefunctions (with projections on occupied states).
322 ! Magnetooptics is implemented only for projections of corrections to wavefunctions on unoccupied states.
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."
327 call messages_warning(2, namespace=sys%namespace)
328 em_vars%calc_magnetooptics = .false.
329 else
330 em_vars%nfactor = 2
331 em_vars%freq_factor(1) = m_one
332 em_vars%freq_factor(2) = -m_one
333 end if
334 end if
335
336 magnetic_pert = .false.
337 select type(ptr => em_vars%perturbation)
339 em_vars%nsigma = 1
340 if (use_kdotp) call messages_experimental("Magnetic perturbation for periodic systems", namespace=sys%namespace)
341 magnetic_pert = .true.
342 end select
343
344 if (em_vars%calc_magnetooptics .or. magnetic_pert) then
345 em_vars%occ_response = .false.
346
347 if (use_kdotp) then
348 pert2_none => perturbation_none_t(sys%namespace)
349 call pert2_none%setup_dir(1)
350
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.)
360 end if
361 end do
362 end do
363
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."
367 else
368 message(1) = "All directions should be periodic for magnetooptics with kdotp."
369 end if
370 call messages_fatal(1, namespace=sys%namespace)
371 end if
372 if (.not. complex_response) then
373 do idir = 1, sys%space%dim
374 call dlr_orth_response(sys%gr, sys%st, kdotp_lr(idir, 1), m_zero)
375 end do
376 else
377 do idir = 1, sys%space%dim
378 call zlr_orth_response(sys%gr, sys%st, kdotp_lr(idir, 1), m_z0)
379 end do
380 end if
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)
383 end if
384 end if
385
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)
390 end do
391
392 if (magnetic_pert .and. sys%st%d%nspin == 1 .and. states_are_real(sys%st)) then
393 ! first-order response is zero if there is time-reversal symmetry. F Mauri and SG Louie, PRL 76, 4246 (1996)
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)
396 ! set HamiltonianVariation to V_ext_only, in magnetic case
397 else
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)
400 ! otherwise, use default, which is hartree + fxc
401 end if
402
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."
406 call messages_warning(1, namespace=sys%namespace)
407 end if
408
409
410 if (sys%st%system_grp%is_root()) then
411 call info()
412 call io_mkdir(em_resp_dir, sys%namespace) ! output
413 end if
414
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)
421 end do
422 end do
423 end do
424
425 select type(ptr=> em_vars%perturbation)
427 !Do nothing
428 class default
429 em_vars%kpt_output = .false.
430 end select
431 if (.not. use_kdotp .or. sys%st%nik == 1) em_vars%kpt_output = .false.
432
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))
435 end if
436
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)
441 else
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)
444 call sternheimer_build_kxc(sh_mo, sys%namespace, sys%gr, sys%st, sys%ks%xc)
445 end if
446 call messages_experimental("Magneto-optical response", namespace=sys%namespace)
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
450 call lr_init(b_lr(idir, 1))
451 call lr_allocate(b_lr(idir, 1), sys%st, sys%gr, allocate_rho = allocate_rho_mo)
452 end do
453
454 if (use_kdotp) then
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))
457 end if
458 nfactor_ke = 1
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.)
467 end do
468 end do
469 end do
470 end do
471 else
472 pert_b => perturbation_magnetic_t(sys%namespace, sys%ions)
473 end if
474 end if
475
476
477 last_omega = m_huge
478 do iomega = 1, em_vars%nomega
479
480 em_vars%ok(1:3) = .true.
481
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)
487
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."
490 call messages_warning(1, namespace=sys%namespace)
491 end if
492
493 ierr = 0
494 ierr_e(:) = 0
495 ierr_e2(:) = 0
496
497 have_to_calculate = .true.
498 opp_freq = .false.
499
500 ! if this frequency is zero and this is not the first
501 ! iteration we do not have to do anything
502 if (iomega > 1 .and. abs(em_vars%freq_factor(ifactor)) <= m_epsilon) have_to_calculate = .false.
503
504 if (ifactor > 1 .and. (.not. em_vars%calc_magnetooptics)) then
505
506 ! if this frequency is the same as the previous one, just copy it
507 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
508 - frequency) < m_epsilon) then
509
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))
513
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))
520 end do
521 end if
522 end do
523
524 have_to_calculate = .false.
525
526 end if
527
528 ! if this frequency is minus the previous one, copy it inverted
529 if (have_to_calculate .and. abs(em_vars%freq_factor(ifactor - 1) * em_vars%omega(iomega) &
530 + frequency) < m_epsilon) then
531
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))
535
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))
542 end do
543 end if
544 end do
545
546 have_to_calculate = .false.
547
548 end if
549
550 end if
551
552 if (iomega > 1 .and. ifactor == 1 .and. (.not. em_vars%calc_magnetooptics)) then
553
554 ! if this frequency is the same as the previous one, just copy it
555 if (have_to_calculate .and. abs(frequency - last_omega) < m_epsilon) then
556
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))
560
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))
567 end do
568 end if
569 end do
570
571 have_to_calculate = .false.
572
573 end if
574
575 ! if this frequency is minus the previous one, copy it inverted
576 if (have_to_calculate .and. abs(frequency + last_omega) < m_epsilon) then
577
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))
581
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))
588 end do
589 end if
590 end do
591
592 have_to_calculate = .false.
593
594 end if
595
596 end if
597
598 if (have_to_calculate) then
599
600 exact_freq(:) = .false.
601
602 if (states_are_real(sys%st)) then
603 call drun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
604 sys%ions)
605 else
606 call zrun_sternheimer(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
607 sys%ions)
608 end if
609
610 end if ! have_to_calculate
611
612 if (.not. have_to_calculate) cycle
613
614 if (states_are_real(sys%st)) then
615 call dcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
616 sys%ions, sys%outp)
617 else
618 call zcalc_properties_linear(em_vars, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%ks%xc, &
619 sys%ions, sys%outp)
620 end if
621
622 end do ! ifactor
623
624 if (states_are_real(sys%st)) then
625 call dcalc_properties_nonlinear(em_vars, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc)
626 else
627 call zcalc_properties_nonlinear(em_vars, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc)
628 end if
629
630 last_omega = em_vars%freq_factor(em_vars%nfactor) * em_vars%omega(iomega)
631
632 end do ! iomega
633
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))
638 end do
639 end do
640 end do
641
642 call sternheimer_end(sh)
643 deallocate(em_vars%perturbation)
644
645 if (use_kdotp) then
646 do idir = 1, sys%space%periodic_dim
647 call lr_dealloc(kdotp_lr(idir, 1))
648 end do
649 end if
650
651 if (em_vars%calc_hyperpol .and. use_kdotp) then
652 call sternheimer_end(sh_kdotp)
653 call sternheimer_end(sh2)
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))
661 end do
662 end do
663 end do
664 end do
665 safe_deallocate_a(kdotp_em_lr2)
666 safe_deallocate_a(dl_eig)
667 end if
668
669 if (em_vars%kpt_output) then
670 safe_deallocate_a(em_vars%alpha_k)
671 end if
672
673 if (em_vars%calc_magnetooptics .or. magnetic_pert) then
674 if (use_kdotp) then
675 safe_deallocate_p(pert2_none)
676 call sternheimer_end(sh_kmo)
677 do idir = 1, sys%space%dim
678 do idir2 = 1, sys%space%dim
679 call lr_dealloc(kb_lr(idir, idir2, 1))
680 if (idir2 <= idir) call lr_dealloc(k2_lr(idir, idir2, 1))
681 end do
682 end do
683 safe_deallocate_a(k2_lr)
684 safe_deallocate_a(kb_lr)
685 end if
686 end if
687
688 if (em_vars%calc_magnetooptics) then
689 if (.not. em_vars%magnetooptics_nohvar) call sternheimer_unset_kxc(sh_mo)
690 call sternheimer_end(sh_mo)
691 do idir = 1, sys%space%dim
692 call lr_dealloc(b_lr(idir, 1))
693 end do
694 safe_deallocate_a(b_lr)
695
696 if (use_kdotp) then
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))
702 end do
703 end do
704 end do
705 end do
706 safe_deallocate_a(ke_lr)
707 if (em_vars%kpt_output) then
708 safe_deallocate_a(em_vars%alpha_be_k)
709 end if
710 else
711 safe_deallocate_p(pert_b)
712 end if
713 end if
714
715 safe_deallocate_a(em_vars%omega)
716 safe_deallocate_a(em_vars%lr)
717 do ifactor = 1, em_vars%nfactor
718 call born_charges_end(em_vars%Born_charges(ifactor))
719 end do
720 call states_elec_deallocate_wfns(sys%st)
721
722 pop_sub(em_resp_run_legacy)
723 contains
724
725 ! ---------------------------------------------------------
726 subroutine parse_input()
727
728 type(block_t) :: blk
729 integer :: nrow, irow, nfreqs_in_row, ifreq, istep, perturb_type
730 real(real64) :: omega_ini, omega_fin, domega
731 logical :: freq_sort
732
734
735 call messages_obsolete_variable(sys%namespace, 'PolFreqs ', 'EMFreqs ')
736 call messages_obsolete_variable(sys%namespace, 'PolHyper ', 'EMHyperpol ')
737 call messages_obsolete_variable(sys%namespace, 'PolEta ', 'EMEta ')
738 call messages_obsolete_variable(sys%namespace, 'PolHamiltonianVariation', 'HamiltonianVariation')
739
740 !%Variable EMFreqs
741 !%Type block
742 !%Section Linear Response::Polarizabilities
743 !%Description
744 !% This block defines for which frequencies the polarizabilities
745 !% will be calculated. If it is not present, the static (<math>\omega = 0</math>) response
746 !% is calculated.
747 !%
748 !% Each row of the block indicates a sequence of frequency values, the
749 !% first column is an integer that indicates the number of steps, the
750 !% second number is the initial frequency, and the third number the final
751 !% frequency. If the first number is one, then only the initial value is
752 !% considered. The block can have any number of rows. Consider the next example:
753 !%
754 !% <tt>%EMFreqs
755 !% <br>31 | 0.0 | 1.0
756 !% <br> 1 | 0.32
757 !% <br>%</tt>
758 !%
759 !%End
760
761 if (parse_block(sys%namespace, 'EMFreqs', blk) == 0) then
762
763 nrow = parse_block_n(blk)
764 em_vars%nomega = 0
765
766 !count the number of frequencies
767 do irow = 0, nrow-1
768 call parse_block_integer(blk, irow, 0, nfreqs_in_row)
769 if (nfreqs_in_row < 1) then
770 message(1) = "EMFreqs: invalid number of frequencies."
771 call messages_fatal(1, namespace=sys%namespace)
772 end if
773 em_vars%nomega = em_vars%nomega + nfreqs_in_row
774 end do
775
776 safe_allocate(em_vars%omega(1:em_vars%nomega))
777
778 !read frequencies
779 ifreq = 1
780 do irow = 0, nrow-1
781 call parse_block_integer(blk, irow, 0, nfreqs_in_row)
782 call parse_block_float(blk, irow, 1, omega_ini)
783 if (nfreqs_in_row > 1) then
784 call parse_block_float(blk, irow, 2, omega_fin)
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
788 end do
789 ifreq = ifreq + nfreqs_in_row
790 else
791 em_vars%omega(ifreq) = omega_ini
792 ifreq = ifreq + 1
793 end if
794 end do
795
796 call parse_block_end(blk)
797
798 !%Variable EMFreqsSort
799 !%Type logical
800 !%Default true
801 !%Section Linear Response::Polarizabilities
802 !%Description
803 !% If true, the frequencies specified by the <tt>EMFreqs</tt> block are sorted, so that
804 !% they are calculated in increasing order. Can be set to false to use the order as stated,
805 !% in case this makes better use of available restart information.
806 !%End
807 call parse_variable(sys%namespace, 'EMFreqsSort', .true., freq_sort)
808
809 if (freq_sort) call sort(em_vars%omega)
810
811 else
812 !there is no frequency block, we calculate response for w = 0.0
813 em_vars%nomega = 1
814 safe_allocate(em_vars%omega(1:em_vars%nomega))
815 em_vars%omega(1) = m_zero
816 end if
817
818 !%Variable EMEta
819 !%Type float
820 !%Default 0.0
821 !%Section Linear Response::Polarizabilities
822 !%Description
823 !% The imaginary part of the frequency, effectively a Lorentzian broadening
824 !% for peaks in the spectrum. It can help convergence of the SCF cycle for the
825 !% Sternheimer equation when on a resonance, and it can be used as a positive
826 !% infinitesimal to get the imaginary parts of response functions at poles.
827 !% In units of energy. Cannot be negative.
828 !%End
829
830 call parse_variable(sys%namespace, 'EMEta', m_zero, em_vars%eta, units_inp%energy)
831 if (em_vars%eta < -m_epsilon) then
832 message(1) = "EMEta cannot be negative."
833 call messages_fatal(1, namespace=sys%namespace)
834 end if
835
836 ! reset the values of these variables
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.
842
843 !%Variable EMPerturbationType
844 !%Type integer
845 !%Default electric
846 !%Section Linear Response::Polarizabilities
847 !%Description
848 !% Which perturbation to consider for electromagnetic linear response.
849 !%Option electric 1
850 !% Electric perturbation used to calculate electric polarizabilities
851 !% and hyperpolarizabilities.
852 !%Option magnetic 2
853 !% Magnetic perturbation used to calculate magnetic susceptibilities.
854 !%Option none 0
855 !% Zero perturbation, for use in testing.
856 !%End
857 call parse_variable(sys%namespace, 'EMPerturbationType', perturbation_electric, perturb_type)
858 call messages_print_var_option('EMPerturbationType', perturb_type, namespace=sys%namespace)
859
860 select case(perturb_type)
861 case(perturbation_electric)
862 em_vars%perturbation => perturbation_electric_t(sys%namespace)
864 em_vars%perturbation => perturbation_magnetic_t(sys%namespace, sys%ions)
866 em_vars%perturbation => perturbation_none_t(sys%namespace)
867 case default
868 assert(.false.)
869 end select
870
871 select type(ptr=>em_vars%perturbation)
873 !%Variable EMCalcRotatoryResponse
874 !%Type logical
875 !%Default false
876 !%Section Linear Response::Polarizabilities
877 !%Description
878 !% Calculate circular-dichroism spectrum from electric perturbation,
879 !% and write to file <tt>rotatory_strength</tt>.
880 !%End
881
882 call parse_variable(sys%namespace, 'EMCalcRotatoryResponse', .false., em_vars%calc_rotatory)
883
884 !%Variable EMHyperpol
885 !%Type block
886 !%Section Linear Response::Polarizabilities
887 !%Description
888 !% This block describes the multiples of the frequency used for
889 !% the dynamic hyperpolarizability. The results are written to the
890 !% file <tt>beta</tt> in the directory for the first multiple.
891 !% There must be three factors, summing to zero: <math>\omega_1 + \omega_2 + \omega_3 = 0</math>.
892 !% For example, for second-harmonic generation, you could use
893 !% <tt>1 | 1 | -2</tt>.
894 !%End
895
896 if (parse_block(sys%namespace, 'EMHyperpol', blk) == 0) then
897 call parse_block_float(blk, 0, 0, em_vars%freq_factor(1))
898 call parse_block_float(blk, 0, 1, em_vars%freq_factor(2))
899 call parse_block_float(blk, 0, 2, em_vars%freq_factor(3))
900
901 call parse_block_end(blk)
902
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."
905 call messages_fatal(1, namespace=sys%namespace)
906 end if
907
908 em_vars%calc_hyperpol = .true.
909 end if
910
911 !%Variable EMCalcMagnetooptics
912 !%Type logical
913 !%Default false
914 !%Section Linear Response::Polarizabilities
915 !%Description
916 !% Calculate magneto-optical response.
917 !%End
918 call parse_variable(sys%namespace, 'EMCalcMagnetooptics', .false., em_vars%calc_magnetooptics)
919
920 !%Variable EMMagnetoopticsNoHVar
921 !%Type logical
922 !%Default true
923 !%Section Linear Response::Polarizabilities
924 !%Description
925 !% Exclude corrections to the exchange-correlation and Hartree terms
926 !% from consideration of perturbations induced by a magnetic field
927 !%End
928 call parse_variable(sys%namespace, 'EMMagnetoopticsNoHVar', .true., em_vars%magnetooptics_nohvar)
929
930 !%Variable EMKPointOutput
931 !%Type logical
932 !%Default false
933 !%Section Linear Response::Polarizabilities
934 !%Description
935 !% Give in the output contributions of different k-points to the dielectric constant.
936 !% Can be also used for magneto-optical effects.
937 !%End
938
939 call parse_variable(sys%namespace, 'EMKPointOutput', .false., em_vars%kpt_output)
940
941 end select
942
943 !%Variable EMForceNoKdotP
944 !%Type logical
945 !%Default false
946 !%Section Linear Response::Polarizabilities
947 !%Description
948 !% If the system is periodic, by default wavefunctions from a previous <tt>kdotp</tt> run will
949 !% be read, to be used in the formulas for the polarizability and
950 !% hyperpolarizability in the quantum theory of polarization. For testing purposes,
951 !% you can set this variable to true to disregard the <tt>kdotp</tt> run, and use the formulas
952 !% for the finite system. This variable has no effect for a finite system.
953 !%End
954
955 call parse_variable(sys%namespace, 'EMForceNoKdotP', .false., em_vars%force_no_kdotp)
956
957 !%Variable EMCalcBornCharges
958 !%Type logical
959 !%Default false
960 !%Section Linear Response::Polarizabilities
961 !%Description
962 !% Calculate linear-response Born effective charges from electric perturbation (experimental).
963 !%End
964
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)
967
968 !%Variable EMOccupiedResponse
969 !%Type logical
970 !%Default false
971 !%Section Linear Response::Polarizabilities
972 !%Description
973 !% Solve for full response without projector into unoccupied subspace.
974 !% Not possible if there are partial occupations.
975 !% When <tt>EMHyperpol</tt> is set for a periodic system, this variable is ignored and
976 !% the full response is always calculated.
977 !%End
978
979 call parse_variable(sys%namespace, 'EMOccupiedResponse', .false., em_vars%occ_response)
980 if (em_vars%occ_response .and. .not. (smear_is_semiconducting(sys%st%smear) .or. sys%st%smear%method == smear_fixed_occ)) then
981 message(1) = "EMOccupiedResponse cannot be used if there are partial occupations."
982 call messages_fatal(1, namespace=sys%namespace)
983 end if
984
985 !%Variable EMWavefunctionsFromScratch
986 !%Type logical
987 !%Default false
988 !%Section Linear Response::Polarizabilities
989 !%Description
990 !% Do not use saved linear-response wavefunctions from a previous run as starting guess.
991 !% Instead initialize to zero as in <tt>FromScratch</tt>, but restart densities will still
992 !% be used. Restart wavefunctions from a very different frequency can hinder convergence.
993 !%End
994
995 call parse_variable(sys%namespace, 'EMWavefunctionsFromScratch', .false., em_vars%wfns_from_scratch)
996
998
999 end subroutine parse_input
1000
1001
1002 ! ---------------------------------------------------------
1003 subroutine info()
1004
1005 push_sub(em_resp_run_legacy.info)
1006
1007 call em_vars%perturbation%info()
1008 select type(ptr=>em_vars%perturbation)
1010 if (em_vars%calc_hyperpol) then
1011 call messages_print_with_emphasis(msg='Linear-Response First-Order Hyperpolarizabilities', namespace=sys%namespace)
1012 else
1013 call messages_print_with_emphasis(msg='Linear-Response Polarizabilities', namespace=sys%namespace)
1014 end if
1015 class default
1016 call messages_print_with_emphasis(msg='Magnetic Susceptibilities', namespace=sys%namespace)
1017 end select
1018
1019 if (states_are_real(sys%st)) then
1020 message(1) = 'Wavefunctions type: Real'
1021 else
1022 message(1) = 'Wavefunctions type: Complex'
1023 end if
1024 call messages_info(1, namespace=sys%namespace)
1025
1026 write(message(1),'(a,i3,a)') 'Calculating response for ', em_vars%nomega, ' frequencies.'
1027 call messages_info(1, namespace=sys%namespace)
1028
1029 call messages_print_with_emphasis(namespace=sys%namespace)
1030
1031 pop_sub(em_resp_run_legacy.info)
1032
1033 end subroutine info
1034
1035! Note: unlike the typical usage, here the templates make 'internal procedures'
1036#include "undef.F90"
1037#include "real.F90"
1038#include "em_resp_inc.F90"
1039
1040#include "undef.F90"
1041#include "complex.F90"
1042#include "em_resp_inc.F90"
1043
1044#include "undef.F90"
1045 end subroutine em_resp_run_legacy
1046
1047
1048 ! ---------------------------------------------------------
1049 subroutine em_resp_output(st, namespace, space, gr, hm, ions, outp, sh, em_vars, iomega, ifactor)
1050 type(states_elec_t), intent(inout) :: st
1051 type(namespace_t), intent(in) :: namespace
1052 class(space_t), intent(in) :: space
1053 type(grid_t), intent(in) :: gr
1054 type(hamiltonian_elec_t), intent(inout) :: hm
1055 type(ions_t), intent(in) :: ions
1056 type(output_t), intent(in) :: outp
1057 type(sternheimer_t), intent(in) :: sh
1058 type(em_resp_t), intent(inout) :: em_vars
1059 integer, intent(in) :: iomega
1060 integer, intent(in) :: ifactor
1061
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)
1067
1068 push_sub(em_resp_output)
1069
1070 use_kdotp = space%is_periodic() .and. .not. em_vars%force_no_kdotp
1071
1072 ! Appended to a header line rather than written as its own line,
1073 ! so that line numbers of the data do not depend on convergence
1074 warning = ""
1075 if (.not. em_vars%ok(ifactor)) warning = " WARNING: not converged"
1076
1077 str_tmp = freq2str(units_from_atomic(units_out%energy, em_vars%freq_factor(ifactor)*em_vars%omega(iomega)))
1078 if (em_vars%calc_magnetooptics) str_tmp = freq2str(units_from_atomic(units_out%energy, em_vars%omega(iomega)))
1079 write(dirname, '(a, a)') em_resp_dir//'freq_', trim(str_tmp)
1080 call io_mkdir(trim(dirname), namespace)
1081
1082 if (sh%has_photons .and. st%system_grp%is_root()) then
1083 iunit = io_open(trim(dirname)//'/photon_coord_q', namespace, action='write')
1084 write(iunit, '(a)') 'Photon coordinate Q [', trim(units_abbrev(units_out%energy)), ']'
1085 write(iunit, '(a)') ' Re Im'
1086 do idir = 1, space%dim
1087 write(iunit, '(f20.6,f20.6)') units_from_atomic(units_out%energy, sum(real(sh%zphoton_coord_q(:, idir)))), &
1088 units_from_atomic(units_out%energy, sum(aimag(sh%zphoton_coord_q(:, idir))))
1089 end do
1090 call io_close(iunit)
1091 end if
1092
1093 call write_eta()
1094
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)
1102 end if
1103
1104 if (space%periodic_dim == space%dim) then
1106 end if
1107
1108 if ((.not. space%is_periodic() .or. em_vars%force_no_kdotp) .and. em_vars%calc_rotatory) then
1110 end if
1111
1112 else
1113 call out_magnetooptics()
1114 if (iomega == 1) call out_susceptibility()
1115 end if
1116
1118 call out_susceptibility()
1119 end select
1120
1122
1123 pop_sub(em_resp_output)
1124
1125 contains
1126
1127
1128 subroutine write_eta()
1129 if (.not. st%system_grp%is_root()) return ! only first node outputs
1130
1131 push_sub(em_resp_output.write_eta)
1132
1133 iunit = io_open(trim(dirname)//'/eta', namespace, action='write')
1134
1135 write(iunit, '(3a)') 'Imaginary part of frequency [', trim(units_abbrev(units_out%energy)), ']'
1136 write(iunit, '(f20.6)') units_from_atomic(units_out%energy, em_vars%eta)
1137
1138 call io_close(iunit)
1139
1140 pop_sub(em_resp_output.write_eta)
1141 end subroutine write_eta
1142
1143
1144 ! ---------------------------------------------------------
1146 subroutine cross_section_header(out_file)
1147 integer, intent(in) :: out_file
1148
1149 character(len=80) :: header_string
1150 integer :: ii, idir, kdir
1151
1152 if (.not. st%system_grp%is_root()) return ! only first node outputs
1153
1155
1156 !this header is the same as spectrum.F90
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)
1160
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)
1165 end do
1166 end do
1167
1168 write(out_file, '(a)', advance = 'no') trim(warning)
1169 write(out_file, *)
1170 write(out_file, '(a1,a20)', advance = 'no') '#', str_center('['//trim(units_abbrev(units_out%energy)) // ']', 20)
1171 do ii = 1, 2 + space%dim**2
1172 write(out_file, '(a20)', advance = 'no') str_center('['//trim(units_abbrev(units_out%length**2)) // ']', 20)
1173 end do
1174 write(out_file,*)
1175
1177 end subroutine cross_section_header
1178
1179
1180 ! ---------------------------------------------------------
1181 subroutine out_polarizability()
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
1185
1186 if (.not. st%system_grp%is_root()) return ! only first node outputs
1187
1189
1190 iunit = io_open(trim(dirname)//'/alpha', namespace, action='write')
1191
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)
1194
1195 call io_close(iunit)
1196
1197 ! CROSS SECTION (THE IMAGINARY PART OF POLARIZABILITY)
1198 if (em_vars%eta > m_epsilon) then
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)
1201
1202 do idir = 1, space%dim
1203 do idir2 = 1, space%dim
1204 cross(idir, idir2) = units_from_atomic(units_out%length**2, cross(idir, idir2))
1205 end do
1206 end do
1207
1208 iunit = io_open(trim(dirname)//'/cross_section', namespace, action='write')
1209
1210 crossp(1:space%dim, 1:space%dim) = matmul(cross(1:space%dim, 1:space%dim), cross(1:space%dim, 1:space%dim))
1211
1212 cross_sum = m_zero
1213 crossp_sum = m_zero
1214 do idir = 1, space%dim
1215 cross_sum = cross_sum + cross(idir, idir)
1216 crossp_sum = crossp_sum + crossp(idir, idir)
1217 end do
1218
1219 anisotropy = crossp_sum - m_third * cross_sum**2
1220
1221 call cross_section_header(iunit)
1222 write(iunit,'(3e20.8)', advance = 'no') &
1223 units_from_atomic(units_out%energy, em_vars%freq_factor(ifactor)*em_vars%omega(iomega)), &
1224 cross_sum * m_third, sqrt(max(anisotropy, m_zero))
1225 do idir = 1, space%dim
1226 do idir2 = 1, space%dim
1227 write(iunit,'(e20.8)', advance = 'no') cross(idir, idir2)
1228 end do
1229 end do
1230 write(iunit,'(a)', advance = 'yes')
1231
1232 call io_close(iunit)
1233 end if
1234
1236 end subroutine out_polarizability
1237
1238
1239 ! ---------------------------------------------------------
1241 subroutine out_dielectric_constant()
1242 integer :: idir, idir1, ik
1243 character(len=80) :: header_string
1244 complex(real64), allocatable :: epsilon_k(:, :, :)
1245
1246 if (.not. st%system_grp%is_root()) return ! only first node outputs
1247
1249
1250 iunit = io_open(trim(dirname)//'/epsilon', namespace, action='write')
1251
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
1256 end do
1257
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)
1260 write(iunit, '(a)')
1261 write(iunit, '(a)') '# Imaginary part of dielectric constant'
1262 call output_tensor(aimag(epsilon(1:space%dim, 1:space%dim)), space%dim, unit_one, iunit=iunit)
1263
1264 if (em_vars%lrc_kernel) then
1265 write(iunit, '(a)')
1266 write(iunit, '(a)') '# Without G = G'' = 0 term of the LRC kernel'
1267
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
1272 end do
1273
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)
1276 write(iunit, '(a)')
1277 write(iunit, '(a)') '# Imaginary part of dielectric constant'
1278 call output_tensor(aimag(epsilon(1:space%dim, 1:space%dim)), space%dim, unit_one, iunit=iunit)
1279 end if
1280
1281 call io_close(iunit)
1282
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
1289 end do
1290 end do
1291 end do
1292 iunit = io_open(trim(dirname)//'/epsilon_k_re', namespace, action='write')
1293
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)
1300
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)
1305 end do
1306 end do
1307 write(iunit, *)
1308
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)
1314 end do
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)
1318 end do
1319 end do
1320 write(iunit, *)
1321 end do
1322 call io_close(iunit)
1323
1324 iunit = io_open(trim(dirname)//'/epsilon_k_im', namespace, action='write')
1325
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)
1332
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)
1337 end do
1338 end do
1339 write(iunit, *)
1340
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)
1346 end do
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))
1350 end do
1351 end do
1352 write(iunit, *)
1353 end do
1354 call io_close(iunit)
1355 safe_deallocate_a(epsilon_k)
1356 end if
1357
1359 end subroutine out_dielectric_constant
1360
1361
1362 ! ---------------------------------------------------------
1363 subroutine out_susceptibility()
1364
1365 character(len=80) :: dirname1
1366
1367 if (.not. st%system_grp%is_root()) return ! only first node outputs
1368
1370
1371 select type(ptr=>em_vars%perturbation)
1373 write(dirname1, '(a)') em_resp_dir//'freq_0.0000'
1374 call io_mkdir(trim(dirname1), namespace)
1375 iunit = io_open(trim(dirname1)//'/susceptibility', namespace, action='write')
1376 class default
1377 iunit = io_open(trim(dirname)//'/susceptibility', namespace, action='write')
1378 end select
1379
1380 ! There is no separation into the diamagnetic and paramagnetic terms in the expression
1381 ! for periodic systems
1382 if (.not. use_kdotp) then
1383 write(iunit, '(2a)') '# Paramagnetic contribution to the susceptibility tensor [ppm a.u.]'
1384 call output_tensor(real(em_vars%chi_para(:, :), real64), space%dim, unit_ppm, iunit=iunit)
1385 write(iunit, '(1x)')
1386
1387 write(iunit, '(2a)') '# Diamagnetic contribution to the susceptibility tensor [ppm a.u.]'
1388 call output_tensor(real(em_vars%chi_dia(:, :), real64), space%dim, unit_ppm, iunit=iunit)
1389 write(iunit, '(1x)')
1390 end if
1391
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) , &
1394 space%dim, unit_ppm, iunit=iunit)
1395 write(iunit, '(1x)')
1396
1397 write(iunit, '(a)') hyphens
1398
1399 if (.not. use_kdotp) then
1400 write(iunit, '(2a)') '# Paramagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1401 call output_tensor(real(em_vars%chi_para(:, :), real64), space%dim, unit_susc_ppm_cgs, iunit=iunit)
1402 write(iunit, '(1x)')
1403
1404 write(iunit, '(2a)') '# Diamagnetic contribution to the susceptibility tensor [ppm cgs / mol]'
1405 call output_tensor(real(em_vars%chi_dia(:, :), real64), space%dim, unit_susc_ppm_cgs, iunit=iunit)
1406 write(iunit, '(1x)')
1407 end if
1408
1409 write(iunit, '(2a)') '# Total susceptibility tensor [ppm cgs / mol]'
1410 call output_tensor(real(em_vars%chi_para(:, :) + em_vars%chi_dia(:,:), real64), &
1411 space%dim, unit_susc_ppm_cgs, iunit=iunit)
1412 write(iunit, '(1x)')
1413
1414 if (use_kdotp) then
1415 write(iunit, '(a)') hyphens
1416 write(iunit, '(1a)') '# Magnetization [ppm a.u.]'
1417 write(iunit, '(3f20.8)') units_from_atomic(unit_ppm, real(em_vars%magn(1), real64)), &
1418 units_from_atomic(unit_ppm, real(em_vars%magn(2), real64)), &
1419 units_from_atomic(unit_ppm, real(em_vars%magn(3), real64))
1420 end if
1421
1422 call io_close(iunit)
1424 end subroutine out_susceptibility
1425
1426
1427 ! ---------------------------------------------------------
1428 subroutine out_wfn_and_densities()
1429 integer :: idir, isigma
1430
1432
1433 do idir = 1, space%dim
1434 if (states_are_complex(st)) then
1435
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, &
1438 units_out%force)
1439 end do
1440 else
1441
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, &
1444 units_out%force)
1445 end do
1446
1447 end if
1448 end do
1449
1451
1452 end subroutine out_wfn_and_densities
1453
1454
1455 ! ---------------------------------------------------------
1458 subroutine out_circular_dichroism()
1459
1460 type(perturbation_magnetic_t), pointer :: angular_momentum
1461 integer :: idir
1462 real(real64) :: ff
1463 complex(real64) :: dic
1464 complex(real64), allocatable :: psi(:, :, :, :)
1465
1467
1468 if (states_are_complex(st) .and. em_vars%nsigma == 2) then
1469
1470 message(1) = "Info: Calculating rotatory response."
1471 call messages_info(1, namespace=namespace)
1472
1473 angular_momentum => perturbation_magnetic_t(namespace, ions)
1474
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))
1476
1477 call states_elec_get_state(st, gr, psi)
1478
1479 dic = m_zero
1480 do idir = 1, space%dim
1481 call angular_momentum%setup_dir(idir)
1482 dic = dic &
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)
1487 end do
1488
1489 safe_deallocate_a(psi)
1490
1491 safe_deallocate_p(angular_momentum)
1492
1493 dic = dic*m_zi*m_half
1494
1495 if (st%system_grp%is_root()) then ! only first node outputs
1496
1497 iunit = io_open(trim(dirname)//'/rotatory_strength', namespace, action='write')
1498
1499 ! print header
1500 write(iunit, '(a1,a20,a20,a20)') '#', str_center("Energy", 20), str_center("R", 20), str_center("Re[beta]", 20)
1501 write(iunit, '(a1,a20,a20,a20)') '#', str_center('['//trim(units_abbrev(units_out%energy)) // ']', 20), &
1502 str_center('['//trim(units_abbrev(units_out%length**3)) //']', 20), &
1503 str_center('['//trim(units_abbrev(units_out%length**4)) //']', 20)
1504
1505 ff = m_zero
1506 if (abs(em_vars%omega(iomega)) > m_epsilon) ff = real(dic, real64) /(m_three*em_vars%omega(iomega))
1507
1508 write(iunit, '(3e20.8)') units_from_atomic(units_out%energy, em_vars%omega(iomega)), &
1509 units_from_atomic(units_out%length**3, aimag(dic)/(p_c*m_pi)), units_from_atomic(units_out%length**4, ff)
1510
1511 call io_close(iunit)
1512 end if
1513 end if
1514
1516
1517 end subroutine out_circular_dichroism
1518
1519 ! ---------------------------------------------------------
1520 subroutine out_magnetooptics
1521 integer :: idir, ik
1522 complex(real64) :: epsilon_m(4), diff(4), eps_mk(space%dim)
1523
1524 if (.not. st%system_grp%is_root()) return ! only first node outputs
1525
1527
1528 ! This code assumes 3D
1529 assert(space%dim == 3)
1530
1531 diff(:) = m_zero
1532 do idir = 1, space%dim
1533 diff(idir) = m_half * (em_vars%alpha_be(magn_dir(idir, 1), magn_dir(idir, 2), idir) - &
1534 em_vars%alpha_be(magn_dir(idir, 2), magn_dir(idir, 1), idir))
1535 end do
1536 diff(4) = (diff(1) + diff(2) + diff(3)) / m_three
1537
1538 iunit = io_open(trim(dirname)//'/alpha_mo', namespace, action='write')
1539
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)
1546 write(iunit, *)
1547
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)
1551 end do
1552 write(iunit, *)
1553
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))
1557 end do
1558 write(iunit, *)
1559
1560 if (space%is_periodic()) then
1561 ! This code assumes 3D periodic
1562 assert(space%periodic_dim == 3)
1563
1564 do idir = 1, space%dim
1565 epsilon_m(idir) = 4 * m_pi * diff(idir) / ions%latt%rcell_volume
1566 end do
1567 epsilon_m(4) = 4 * m_pi * diff(4) / ions%latt%rcell_volume
1568
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)
1572 end do
1573 write(iunit, *)
1574
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))
1578 end do
1579 write(iunit, *)
1580
1581 if (em_vars%lrc_kernel) then
1582 write(iunit, '(a)')
1583 write(iunit, '(a)') '# Without the G = G'' = 0 term of the LRC kernel'
1584
1585 diff(:) = m_zero
1586 epsilon_m(:) = m_zero
1587 do idir = 1, space%dim
1588 diff(idir) = m_half * (em_vars%alpha_be0(magn_dir(idir, 1), magn_dir(idir, 2), idir) - &
1589 em_vars%alpha_be0(magn_dir(idir, 2), magn_dir(idir, 1), idir))
1590
1591 epsilon_m(idir) = 4 * m_pi * diff(idir) / ions%latt%rcell_volume
1592 end do
1593 diff(4) = (diff(1) + diff(2) + diff(3)) / m_three
1594 epsilon_m(4) = 4 * m_pi * diff(4) / ions%latt%rcell_volume
1595
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)
1601 write(iunit, *)
1602
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)
1606 end do
1607 write(iunit, *)
1608
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))
1612 end do
1613 write(iunit, *)
1614
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)
1618 end do
1619 write(iunit, *)
1620
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))
1624 end do
1625 write(iunit, *)
1626 end if
1627 end if
1628 call io_close(iunit)
1629
1630 if (space%is_periodic() .and. em_vars%kpt_output) then
1631 iunit = io_open(trim(dirname)//'/epsilon_mo_k', namespace, action='write')
1632
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)
1645 write(iunit, *)
1646
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
1651 eps_mk(idir) = m_two * m_pi * (em_vars%alpha_be_k(magn_dir(idir, 1), magn_dir(idir, 2), idir, ik) - &
1652 em_vars%alpha_be_k(magn_dir(idir, 2), magn_dir(idir, 1), idir, ik)) / ions%latt%rcell_volume
1653 end do
1654
1655 do idir = 1, space%dim
1656 write(iunit, '(e20.8)', advance = 'no') hm%kpoints%reduced%red_point(idir, ik)
1657 end do
1658 do idir = 1, space%dim
1659 write(iunit, '(e20.8)', advance = 'no') real(eps_mk(idir), real64)
1660 end do
1661 do idir = 1, space%dim
1662 write(iunit, '(e20.8)', advance = 'no') aimag(eps_mk(idir))
1663 end do
1664 write(iunit, *)
1665 end do
1666 call io_close(iunit)
1667 end if
1668
1670 end subroutine out_magnetooptics
1671
1672 end subroutine em_resp_output
1673
1674 ! ---------------------------------------------------------
1678 subroutine out_hyperpolarizability(box, beta, freq_factor, converged, dirname, namespace)
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
1684 type(namespace_t), intent(in) :: namespace
1685
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
1689
1690 push_sub(out_hyperpolarizability)
1691
1692 ! Output first hyperpolarizability (beta)
1693 iunit = io_open(trim(dirname)//'/beta', namespace, action='write')
1694
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), ') [', &
1697 trim(units_abbrev(units_out%hyperpolarizability)), ']'
1698 if (.not. converged) write(iunit, '(a)', advance='no') ' WARNING: not converged'
1699
1700 write(iunit, '()')
1701
1702 do ii = 1, box%dim
1703 do jj = 1, box%dim
1704 do kk = 1, box%dim
1705 write(iunit,'(a,e20.8,e20.8)') 'beta '// &
1706 index2axis(ii)//index2axis(jj)//index2axis(kk)//' ', &
1707 units_from_atomic(units_out%hyperpolarizability, real( beta(ii, jj, kk), real64)) , &
1708 units_from_atomic(units_out%hyperpolarizability, aimag(beta(ii, jj, kk)))
1709 end do
1710 end do
1711 end do
1712
1713 if (box%dim == 3) then
1714 bpar = m_zero
1715 bper = m_zero
1716
1717 do ii = 1, box%dim
1718 do jj = 1, box%dim
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)
1721 end do
1722 end do
1723
1724 write(iunit, '()')
1725
1726 bpar = bpar / m_five
1727 bper = bper / m_five
1728 bk(1:box%dim) = m_three*m_half*(bpar(1:box%dim) - bper(1:box%dim))
1729
1730 do ii = 1, box%dim
1731 write(iunit, '(a, 2e20.8)') 'beta // '//index2axis(ii), &
1732 units_from_atomic(units_out%hyperpolarizability, real(bpar(ii), real64)), &
1733 units_from_atomic(units_out%hyperpolarizability, aimag(bpar(ii)))
1734 end do
1735
1736 write(iunit, '()')
1737
1738 do ii = 1, box%dim
1739 write(iunit, '(a, 2e20.8)') 'beta _L '//index2axis(ii), &
1740 units_from_atomic(units_out%hyperpolarizability, real(bper(ii), real64)), &
1741 units_from_atomic(units_out%hyperpolarizability, aimag(bper(ii)))
1742 end do
1743
1744 write(iunit, '()')
1745
1746 do ii = 1, box%dim
1747 write(iunit, '(a, 2e20.8)') 'beta k '//index2axis(ii), &
1748 units_from_atomic(units_out%hyperpolarizability, real(bk(ii), real64)), &
1749 units_from_atomic(units_out%hyperpolarizability, aimag(bk(ii)))
1750 end do
1751
1752 call calc_beta_hrs(box, beta, hrs_vv, hrs_hv)
1753
1754 write(iunit, '()')
1755 write(iunit, '(a)') 'beta for liquid- or gas-phase hyper-Rayleigh scattering:'
1756 write(iunit, '(a, 2e20.8)') 'VV polarization ', &
1757 units_from_atomic(units_out%hyperpolarizability, real(sqrt(hrs_vv), real64)), &
1758 units_from_atomic(units_out%hyperpolarizability, aimag(sqrt(hrs_vv)))
1759 write(iunit, '(a, 2e20.8)') 'HV polarization ', &
1760 units_from_atomic(units_out%hyperpolarizability, real(sqrt(hrs_hv), real64)), &
1761 units_from_atomic(units_out%hyperpolarizability, aimag(sqrt(hrs_hv)))
1762 end if
1763
1764 call io_close(iunit)
1766
1767 contains
1768
1769 ! ---------------------------------------------------------
1774 subroutine calc_beta_hrs(box, beta, HRS_VV, HRS_HV)
1775 class(box_t), intent(in) :: box
1776 complex(real64), intent(in) :: beta(:, :, :)
1777 complex(real64), intent(out) :: HRS_VV, HRS_HV
1778
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
1781 integer :: ii, jj
1782
1784
1785 ! first calculate VV (vertical-vertical) polarization, FFF in Decius et al.
1786 hrs_a = m_zero
1787 do ii = 1, box%dim
1788 hrs_a = hrs_a + beta(ii,ii,ii)**2
1789 end do
1790
1791 hrs_b = m_zero
1792 hrs_c = m_zero
1793 do ii = 1, box%dim
1794 do jj = 1, box%dim
1795 if (ii /= jj) then
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
1798 end if
1799 end do
1800 end do
1801
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))
1805
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
1807
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
1813
1814 ! now calculate HV (horizontal-vertical) polarization, FGG in Decius et al.
1815 hrs_b1 = m_zero
1816 hrs_b2 = m_zero
1817 hrs_c1 = m_zero
1818 hrs_c2 = m_zero
1819 hrs_c3 = m_zero
1820 do ii = 1, box%dim
1821 do jj = 1, box%dim
1822 if (ii /= jj) then
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
1828 end if
1829 end do
1830 end do
1831
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)
1841
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
1845
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
1861
1863 end subroutine calc_beta_hrs
1864
1865 end subroutine out_hyperpolarizability
1866
1867end module em_resp_oct_m
1868
1869!! Local Variables:
1870!! mode: f90
1871!! coding: utf-8
1872!! End:
subroutine out_dielectric_constant()
epsilon = 1 + 4 * pi * alpha/volume
Definition: em_resp.F90:2868
subroutine write_eta()
Definition: em_resp.F90:2755
subroutine calc_beta_hrs(box, beta, HRS_VV, HRS_HV)
calculate hyper-Rayleigh scattering hyperpolarizabilities SJ Cyvin, JE Rauch, and JC Decius,...
Definition: em_resp.F90:3401
subroutine out_circular_dichroism()
See D Varsano, LA Espinosa Leal, Xavier Andrade, MAL Marques, Rosa di Felice, Angel Rubio,...
Definition: em_resp.F90:3085
subroutine out_magnetooptics
Definition: em_resp.F90:3147
subroutine out_susceptibility()
Definition: em_resp.F90:2990
subroutine info()
Definition: em_resp.F90:1099
subroutine dcalc_properties_linear(em_vars, namespace, space, gr, kpoints, st, hm, xc, ions, outp)
Definition: em_resp.F90:1703
subroutine out_wfn_and_densities()
Definition: em_resp.F90:3055
subroutine drun_sternheimer(em_vars, namespace, space, gr, kpoints, st, hm, mc, ions)
Definition: em_resp.F90:1199
subroutine out_polarizability()
Definition: em_resp.F90:2808
subroutine dcalc_properties_nonlinear(em_vars, namespace, space, gr, st, hm, xc)
Definition: em_resp.F90:1850
subroutine zrun_sternheimer(em_vars, namespace, space, gr, kpoints, st, hm, mc, ions)
Definition: em_resp.F90:1957
subroutine parse_input()
Definition: em_resp.F90:822
subroutine cross_section_header(out_file)
Note: this should be in spectrum.F90.
Definition: em_resp.F90:2773
subroutine zcalc_properties_nonlinear(em_vars, namespace, space, gr, st, hm, xc)
Definition: em_resp.F90:2608
subroutine zcalc_properties_linear(em_vars, namespace, space, gr, kpoints, st, hm, xc, ions, outp)
Definition: em_resp.F90:2461
This is the common interface to a sorting routine. It performs the shell algorithm,...
Definition: sort.F90:156
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
Definition: em_resp.F90:175
subroutine em_resp_run_legacy(sys, fromScratch)
Definition: em_resp.F90:252
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.
Definition: em_resp.F90:3305
subroutine, public em_resp_run(system, from_scratch)
Definition: em_resp.F90:234
subroutine em_resp_output(st, namespace, space, gr, hm, ions, outp, sh, em_vars, iomega, ifactor)
Definition: em_resp.F90:2676
integer, parameter perturbation_none
Definition: em_resp.F90:175
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_huge
Definition: global.F90:218
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_third
Definition: global.F90:207
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
complex(real64), parameter, public m_z0
Definition: global.F90:210
complex(real64), parameter, public m_zi
Definition: global.F90:214
real(real64), parameter, public m_epsilon
Definition: global.F90:216
character(len= *), parameter, public em_resp_dir
Definition: global.F90:281
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:242
real(real64), parameter, public m_one
Definition: global.F90:201
real(real64), parameter, public m_three
Definition: global.F90:203
real(real64), parameter, public m_five
Definition: global.F90:205
This module implements the underlying real-space grid.
Definition: grid.F90:119
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
character(len=100) function, public kdotp_wfs_tag(dir, dir2)
Definition: kdotp_calc.F90:154
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)
Definition: loct.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=68), parameter, public hyphens
Definition: messages.F90:163
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1040
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
This module implements the basic mulsisystem class, a container system for other systems.
this module contains the low-level part of the output system
Definition: output_low.F90:117
this module contains the output system
Definition: output.F90:117
subroutine, public zoutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
Definition: output.F90:1737
subroutine, public doutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
Definition: output.F90:1970
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
integer, parameter, public restart_kdotp
Definition: restart.F90:156
integer, parameter, public restart_gs
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:184
integer, parameter, public smear_fixed_occ
Definition: smear.F90:176
logical pure function, public smear_is_semiconducting(this)
Definition: smear.F90:1042
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:119
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
Definition: string.F90:176
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
This module defines the unit system, used for input and output.
type(unit_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.
Definition: utils.F90:120
subroutine, public output_tensor(tensor, ndim, unit, write_average, iunit, namespace)
Definition: utils.F90:245
character pure function, public index2axis(idir)
Definition: utils.F90:205
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:665
Definition: xc.F90:120
class to tell whether a point is inside or outside
Definition: box.F90:143
Class describing the electron system.
Definition: electrons.F90:222
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Container class for lists of system_oct_m::system_t.
output handler class
Definition: output_low.F90:166
The states_elec_t class contains all electronic wave functions.
int true(void)