30 use,
intrinsic :: iso_fortran_env
63 real(real64),
allocatable :: rcoords(:,:)
64 real(real64),
allocatable :: rcoords_nrm(:,:)
65 complex(real64),
allocatable,
public :: wf(:,:,:,:,:)
66 real(real64),
allocatable :: dq(:,:)
67 real(real64),
allocatable :: domega(:)
69 complex(real64),
allocatable :: wfft(:,:,:,:,:)
70 real(real64) :: omegamax
71 real(real64) :: delomega
76 integer :: nstepsphir, nstepsthetar
77 type(mesh_interpolation_t) :: interp
80 integer,
parameter :: &
87 subroutine pes_spm_init(this, namespace, mesh, st, save_iter)
88 type(pes_spm_t),
intent(out) :: this
89 type(namespace_t),
intent(in) :: namespace
90 type(mesh_t),
intent(in) :: mesh
91 type(states_elec_t),
intent(in) :: st
92 integer,
intent(in) :: save_iter
95 integer :: stst, stend, kptst, kptend, sdim, mdim
99 real(real64) :: thetar, phir, radius
100 real(real64) :: xx(mesh%box%dim)
106 kptst = st%d%kpt%start
107 kptend = st%d%kpt%end
111 message(1) =
'Info: Calculating PES using sample point technique.'
128 this%sphgrid = .false.
129 if (
parse_block(namespace,
'PES_spm_points', blk) < 0)
then
130 this%sphgrid = .
true.
133 if (this%sphgrid)
then
134 message(1) =
'Info: Using spherical grid.'
136 message(1) =
'Info: Using sample points from block.'
172 message(1) =
'Info: Calculating PES during time propagation.'
198 call parse_variable(namespace,
'PES_spm_StepsThetaR', 45, this%nstepsthetar)
199 if (this%sphgrid .and. this%nstepsthetar < 0)
call messages_input_error(namespace,
'PES_spm_StepsThetaR')
209 call parse_variable(namespace,
'PES_spm_StepsPhiR', 90, this%nstepsphir)
210 if (this%sphgrid)
then
212 if (this%nstepsphir == 0) this%nstepsphir = 1
222 if (this%sphgrid)
then
228 select type (box => mesh%box)
232 radius = minval(box%half_length(1:mdim))
234 message(1) =
"Spherical grid not implemented for this box shape."
235 message(2) =
"Specify sample points with block PES_spm_points."
243 if (.not. this%sphgrid)
then
249 this%nstepsthetar = 0
251 this%nspoints = this%nstepsphir
254 this%nstepsthetar = 0
255 this%nspoints = this%nstepsphir
258 if (this%nstepsthetar <= 1)
then
260 this%nstepsthetar = 1
262 this%nspoints = this%nstepsphir * (this%nstepsthetar - 1) + 2
273 safe_allocate(this%rcoords(1:mdim, 1:this%nspoints))
274 safe_allocate(this%rcoords_nrm(1:mdim, 1:this%nspoints))
276 if (.not. this%sphgrid)
then
278 message(1) =
'Info: Reading sample points from input.'
282 do isp = 1, this%nspoints
286 this%rcoords(:, isp) = xx(:)
287 this%rcoords_nrm(:, isp) = this%rcoords(:, isp) / norm2(this%rcoords(:, isp))
293 message(1) =
'Info: Initializing spherical grid.'
299 do ith = 0, this%nstepsthetar
300 if (mdim == 3) thetar = ith *
m_pi / this%nstepsthetar
301 do iph = 0, this%nstepsphir - 1
303 phir = iph *
m_two *
m_pi / this%nstepsphir
304 this%rcoords_nrm(1, isp) =
cos(phir) *
sin(thetar)
305 if (mdim >= 2) this%rcoords_nrm(2, isp) =
sin(phir) *
sin(thetar)
306 if (mdim == 3) this%rcoords_nrm(3, isp) =
cos(thetar)
307 this%rcoords(:, isp) = radius * this%rcoords_nrm(:, isp)
308 if (mdim == 3 .and. (ith == 0 .or. ith == this%nstepsthetar))
exit
314 safe_allocate(this%wf(stst:stend, 1:sdim, kptst:kptend, 1:this%nspoints, 0:save_iter-1))
316 if (this%recipe ==
m_phase)
then
317 safe_allocate(this%dq(1:this%nspoints, 0:save_iter-1))
318 safe_allocate(this%domega(0:save_iter-1))
324 this%nomega = nint(this%omegamax/this%delomega)
325 safe_allocate(this%wfft(stst:stend, 1:sdim, kptst:kptend, 1:this%nspoints, 1:this%nomega))
329 this%save_iter = save_iter
341 safe_deallocate_a(this%wf)
342 safe_deallocate_a(this%rcoords)
343 safe_deallocate_a(this%rcoords_nrm)
345 safe_deallocate_a(this%wfft)
347 safe_deallocate_a(this%dq)
348 safe_deallocate_a(this%domega)
355 subroutine pes_spm_calc(this, st, mesh, dt, iter, ext_partners)
358 type(
mesh_t),
intent(in) :: mesh
359 real(real64),
intent(in) :: dt
360 integer,
intent(in) :: iter
363 integer :: stst, stend, kptst, kptend, sdim, mdim
364 integer :: ist, ik, isdim
367 complex(real64),
allocatable :: psistate(:), wfftact(:,:,:,:,:)
368 complex(real64) :: rawfac
369 complex(real64),
allocatable :: phasefac(:)
371 real(real64) :: omega
372 complex(real64),
allocatable :: interp_values(:)
376 itstep = mod(iter-1, this%save_iter)
380 kptst = st%d%kpt%start
381 kptend = st%d%kpt%end
385 safe_allocate(psistate(1:mesh%np_part))
386 safe_allocate(interp_values(1:this%nspoints))
389 safe_allocate(wfftact(1:st%nst, 1:sdim, 1:st%nik, 1:this%nspoints, 1:this%nomega))
393 if (this%recipe ==
m_phase)
then
394 safe_allocate(phasefac(1:this%nspoints))
398 this%wf(:,:,:,:,itstep) =
m_z0
400 do ik = kptst, kptend
405 this%rcoords(1:mdim, 1:this%nspoints), interp_values(1:this%nspoints))
406 this%wf(ist, isdim, ik, :, itstep) = st%occ(ist, ik) * interp_values(:)
411 if (this%recipe ==
m_phase)
then
416 do iom = 1, this%nomega
417 omega = iom*this%delomega
420 if (this%recipe == m_raw)
then
421 wfftact(stst:stend, 1:sdim, kptst:kptend, :, iom) = &
422 rawfac *
sqrt(
m_two * omega) * this%wf(stst:stend, 1:sdim, kptst:kptend, :, itstep)
424 phasefac(:) = rawfac *
exp(
m_zi * (this%domega(itstep) -
sqrt(
m_two * omega) * this%dq(:, itstep)))
426 do ik = kptst, kptend
429 wfftact(ist, isdim, ik, :, iom) = phasefac(:) * this%wf(ist, isdim, ik, :, itstep) *
sqrt(
m_two * omega)
436 this%wfft = this%wfft + wfftact
439 safe_deallocate_a(psistate)
440 safe_deallocate_a(interp_values)
441 safe_deallocate_a(phasefac)
443 safe_deallocate_a(wfftact)
452 class(
mesh_t),
intent(in) :: mesh
455 integer,
intent(in) :: iter
456 real(real64),
intent(in) :: dt
458 integer :: ist, ik, isdim
460 integer :: isp, save_iter, isp_save
461 integer :: iom, ith, iph, iphi, itot
462 real(real64) :: omega, thetar, phir
463 complex(real64) :: vfu
464 real(real64) :: weight
465 real(real64),
allocatable :: spctrsum(:,:,:,:), spctrout(:,:)
466 character(len=80) :: filenr
467 integer :: iunitone, iunittwo
468 integer :: stst, stend, kptst, kptend, sdim, mdim
474 kptst = st%d%kpt%start
475 kptend = st%d%kpt%end
479 save_iter = this%save_iter
482 safe_allocate(spctrsum(1:st%nst, 1:sdim, 1:st%nik, 1:this%nomega))
485 safe_allocate(spctrout(1:this%nspoints, 1:this%nomega))
488 do ik = kptst, kptend
492 if (this%sphgrid)
then
498 do iom = 1, this%nomega
499 spctrsum(ist, isdim, ik, iom) = spctrsum(ist, isdim, ik, iom) + &
500 sum(abs(this%wfft(ist, isdim, ik, :, iom)**
m_two),1) * weight
506 do iom = 1, this%nomega
507 do iph = 0, this%nstepsphir - 1
508 spctrsum(ist, isdim, ik, iom) = spctrsum(ist, isdim, ik, iom) + &
509 abs(this%wfft(ist, isdim, ik, iph, iom))**
m_two * weight
514 do iom = 1, this%nomega
517 do ith = 0, this%nstepsthetar
518 thetar = ith *
m_pi / this%nstepsthetar
520 if (ith == 0 .or. ith == this%nstepsthetar)
then
523 weight = abs(
cos(thetar -
m_pi / this%nstepsthetar /
m_two) - &
527 do iph = 0, this%nstepsphir - 1
529 spctrsum(ist, isdim, ik, iom) = spctrsum(ist, isdim, ik, iom) + &
530 abs(this%wfft(ist, isdim, ik, isp, iom))**
m_two * weight
532 if (ith == 0 .or. ith == this%nstepsthetar)
exit
539 spctrout(1:this%nspoints, 1:this%nomega) = spctrout(1:this%nspoints, 1:this%nomega) + &
540 abs(this%wfft(ist, isdim, ik, 1:this%nspoints, 1:this%nomega))**
m_two
547 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
558 if (this%sphgrid)
then
559 iunittwo =
io_open(
'td.general/'//
'PES_spm.distribution.out', namespace, action=
'write', position=
'rewind')
560 iunitone =
io_open(
'td.general/'//
'PES_spm.power.sum', namespace, action=
'write', position=
'rewind')
561 write(iunitone,
'(a23)')
'# omega, total spectrum'
565 write(iunittwo,
'(a40)')
'# omega, distribution (left/right point)'
567 do iom = 1, this%nomega
568 omega = iom * this%delomega
569 write(iunittwo,
'(5(1x,e18.10E3))') omega, spctrout(2, iom), spctrout(1, iom)
570 write(iunitone,
'(2(1x,e18.10E3))') omega, sum(sum(sum(spctrsum(:,:,:,iom),1),1),1) *
sqrt(
m_two * omega)
574 write(iunittwo,
'(a26)')
'# omega, phi, distribution'
576 do iom = 1, this%nomega
577 omega = iom * this%delomega
579 do iph = 0, this%nstepsphir - 1
580 phir = iph *
m_two *
m_pi / this%nstepsphir
581 write(iunittwo,
'(5(1x,e18.10E3))') omega, phir, spctrout(iph + 1, iom)
584 write(iunittwo,
'(5(1x,e18.10E3))') omega,
m_two *
m_pi, spctrout(1, iom)
585 write(iunittwo,
'(1x)', advance=
'yes')
587 write(iunitone,
'(2(1x,e18.10E3))', advance=
'no') omega, sum(sum(sum(spctrsum(:,:,:,iom),1),1),1) *
sqrt(
m_two * omega)
591 do isdim = 1, st%d%dim
592 write(iunitone,
'(1x,e18.10E3)', advance=
'no') spctrsum(ist, isdim, ik, iom) *
sqrt(
m_two * omega)
596 write(iunitone,
'(1x)', advance=
'yes')
601 write(iunittwo,
'(a33)')
'# omega, theta, phi, distribution'
603 do iom = 1, this%nomega
604 omega = iom * this%delomega
607 do ith = 0, this%nstepsthetar
608 thetar = ith *
m_pi / this%nstepsthetar
610 do iph = 0, this%nstepsphir - 1
613 phir = iph *
m_two *
m_pi / this%nstepsphir
614 if (iph == 0) isp_save = isp
615 write(iunittwo,
'(5(1x,e18.10E3))') omega, thetar, phir, spctrout(isp, iom)
618 if (this%nstepsphir > 1 .and. iph == (this%nstepsphir - 1))
then
619 write(iunittwo,
'(5(1x,e18.10E3))') omega, thetar,
m_two *
m_pi, spctrout(isp_save, iom)
623 if (ith == 0 .or. ith == this%nstepsthetar)
then
624 if (this%nstepsphir > 1)
then
625 do iphi = 1, this%nstepsphir
626 phir = iphi *
m_two *
m_pi / this%nstepsphir
627 write(iunittwo,
'(5(1x,e18.10E3))') omega, thetar, phir, spctrout(isp, iom)
634 if (this%nstepsphir > 1 .or. ith == this%nstepsthetar)
write(iunittwo,
'(1x)', advance=
'yes')
638 write(iunitone,
'(2(1x,e18.10E3))', advance=
'no') omega, sum(sum(sum(spctrsum(:,:,:,iom),1),1),1) *
sqrt(
m_two * omega)
641 do isdim = 1, st%d%dim
642 write(iunitone,
'(1x,e18.10E3)', advance=
'no') spctrsum(ist, isdim, ik, iom) *
sqrt(
m_two * omega)
646 write(iunitone,
'(1x)', advance=
'yes')
659 if (.not. this%sphgrid .or.
debug%info)
then
661 do ik = kptst, kptend
664 itot = ist + (ik-1) * st%nst + (isdim-1) * st%nst*st%d%kpt%nglobal
665 write(*,*)
'TEST', itot
666 write(filenr,
'(i10.10)') itot
668 iunitone =
io_open(
'td.general/'//
'PES_spm.'//trim(filenr)//
'.wavefunctions.out', &
669 namespace, action=
'write', position=
'append')
671 do ii = 1, save_iter - mod(iter, save_iter)
672 jj = iter - save_iter + ii + mod(save_iter - mod(iter, save_iter), save_iter)
675 do isp = 1, this%nspoints
677 write(iunitone,
'(1x,e18.10E3,1x,e18.10E3)', advance=
'no') real(vfu, real64) , aimag(vfu)
679 write(iunitone,
'(1x)', advance=
'yes')
688 do ik = kptst, kptend
691 itot = ist + (ik-1) * st%nst + (isdim-1) * st%nst*st%d%kpt%nglobal
692 write(filenr,
'(i10.10)') itot
694 iunitone =
io_open(
'td.general/'//
'PES_spm.'//trim(filenr)//
'.spectrum.out', &
695 namespace, action=
'write', position=
'rewind')
696 write(iunitone,
'(a48)')
'# frequency, orbital spectrum at sampling points'
698 do iom = 1, this%nomega
699 omega = iom*this%delomega
700 write(iunitone,
'(e17.10, 1x)', advance=
'no') omega
702 do isp = 1, this%nspoints
703 write(iunitone,
'(e17.10, 1x)', advance=
'no') abs(this%wfft(ist, isdim, ik, isp, iom))**
m_two
706 write(iunitone,
'(1x)', advance=
'yes')
717 if (this%recipe ==
m_phase)
then
718 do isp = 1, this%nspoints
719 write(filenr,
'(i10.10)') isp
720 iunittwo =
io_open(
'td.general/'//
'PES_spm.'//trim(filenr)//
'.phase.out', namespace, action=
'write', position=
'append')
722 do ii = 1, save_iter - mod(iter, save_iter)
723 jj = iter - save_iter + ii + mod(save_iter - mod(iter, save_iter), save_iter)
726 write(iunittwo,
'(1x,e18.10E3,1x,e18.10E3)', advance=
'no') this%domega(ii-1), this%dq(isp, ii-1)
727 write(iunittwo,
'(1x)', advance=
'yes')
735 iunitone =
io_open(
'td.general/'//
'PES_spm.total.out', namespace, action=
'write', position=
'rewind')
736 write(iunitone,
'(a46)')
'# frequency, total spectrum at sampling points'
737 do iom = 1, this%nomega
738 omega = iom*this%delomega
740 write(iunitone,
'(e17.10, 1x)', advance=
'no') omega
741 do isp = 1, this%nspoints
742 write(iunitone,
'(e17.10, 1x)', advance=
'no') spctrout(isp, iom)
745 write(iunitone,
'(1x)', advance=
'yes')
752 safe_deallocate_a(spctrout)
753 safe_deallocate_a(spctrsum)
761 type(
mesh_t),
intent(in) :: mesh
765 integer :: ist, ik, isdim
767 real(real64) :: xx(mesh%box%dim)
768 character(len=80) :: filenr
774 if (.not. this%sphgrid .or.
debug%info)
then
775 do isp = 1, this%nspoints
776 write(filenr,
'(i10.10)') isp
778 iunit =
io_open(
'td.general/'//
'PES_spm.'//trim(filenr)//
'.wavefunctions.out', namespace, action=
'write')
779 xx(:) = this%rcoords(1:mesh%box%dim, isp)
780 write(iunit,
'(a1)')
'#'
781 write(iunit,
'(a7,f17.6,a1,f17.6,a1,f17.6,5a)') &
782 '# R = (',xx(1),
' ,',xx(2),
' ,',xx(3), &
785 write(iunit,
'(a1)')
'#'
786 write(iunit,
'(a3,14x)', advance=
'no')
'# t'
789 do isdim = 1, st%d%dim
790 write(iunit,
'(3x,a8,i3,a7,i3,a8,i3,3x)', advance=
'no') &
791 "ik = ", ik,
" ist = ", ist,
" idim = ", isdim
795 write(iunit,
'(1x)', advance=
'yes')
799 if (this%recipe ==
m_phase)
then
800 iunit =
io_open(
'td.general/'//
'PES_spm.'//trim(filenr)//
'.phase.out', namespace, action=
'write')
801 write(iunit,
'(a24)')
'# time, dq(t), dOmega(t)'
816 integer,
intent(out) :: ierr
818 integer :: err, iunit
831 message(1) =
"Debug: Writing PES_spm restart."
840 if (this%recipe ==
m_phase)
then
842 write(iunit, *) this%domega(:), this%dq(:,:)
846 if (err /= 0) ierr = ierr + 1
849 message(1) =
"Debug: Writing PES_spm restart done."
861 integer,
intent(out) :: ierr
863 integer :: err, iunit
877 message(1) =
"Debug: Reading PES_spm restart."
882 call zrestart_read_binary(restart,
'pesspm', this%nspoints*st%d%dim*st%nst*st%nik*this%nomega, &
886 if (this%recipe ==
m_phase)
then
888 read(iunit, *) this%domega(:), this%dq(:,:)
892 if (err /= 0) ierr = ierr + 1
895 message(1) =
"Debug: Reading PES_spm restart done."
907 integer,
intent(in) :: iter
908 real(real64),
intent(in) :: dt
909 integer,
intent(in) :: ii
913 real(real64) :: vp(3)
914 real(real64) :: rdota
921 if(
associated(lasers))
then
922 do il = 1, lasers%no_lasers
929 if (ii == 0) iprev = this%save_iter - 1
931 do isp = 1, this%nspoints
932 rdota = dot_product(this%rcoords_nrm(1:mesh%box%dim, isp), vp(1:mesh%box%dim))
933 this%dq(isp, ii) = this%dq(isp, iprev) + rdota * dt /
p_c
936 this%domega(ii) = this%domega(iprev) + dot_product(vp, vp) / (
m_two *
p_c**
m_two) * dt
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
type(debug_t), save, public debug
type(lasers_t) function, pointer, public list_get_lasers(partners)
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
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_half
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
real(real64), parameter, public m_one
This module defines classes and functions for interaction partners.
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
subroutine, public laser_field(laser, field, time)
Retrieves the value of either the electric or the magnetic field. If the laser is given by a scalar p...
subroutine, public mesh_interpolation_init(this, mesh)
This module defines the meshes, which are used in Octopus.
subroutine, public messages_obsolete_variable(namespace, name, rep)
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
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_input_error(namespace, var, details, row, column)
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
logical function, public parse_is_defined(namespace, name)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
integer, parameter m_phase
subroutine, public pes_spm_dump(restart, this, st, ierr)
subroutine, public pes_spm_init_write(this, mesh, st, namespace)
subroutine, public pes_spm_output(this, mesh, st, namespace, iter, dt)
subroutine, public pes_spm_calc(this, st, mesh, dt, iter, ext_partners)
subroutine, public pes_spm_init(this, namespace, mesh, st, save_iter)
subroutine, public pes_spm_load(restart, this, st, ierr)
subroutine, public pes_spm_end(this)
subroutine pes_spm_calc_rcphase(this, mesh, iter, dt, ext_partners, ii)
subroutine, public restart_close(restart, iunit)
Close a file previously opened with restart_open.
logical pure function, public restart_skip(restart)
Returns true if the restart information should neither be read nor written. This might happen because...
integer function, public restart_open(restart, filename, status, position, silent)
Open file "filename" found inside the current restart directory. Depending on the type of restart,...
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_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
Class implementing a parallelepiped box. Currently this is restricted to a rectangular cuboid (all th...
Class implementing a spherical box.
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.