79 integer,
public,
parameter :: &
93 integer :: mode = tdf_empty
94 real(real64) :: t0 =
m_zero
95 real(real64) :: tau0 =
m_zero
96 real(real64) :: tau1 =
m_zero
97 real(real64) :: a0 =
m_zero
98 real(real64) :: omega0 =
m_zero
99 real(real64) :: dt =
m_zero
100 real(real64) :: init_time =
m_zero
101 real(real64) :: final_time =
m_zero
103 integer :: nfreqs = 0
105 type(spline_t) :: amplitude
106 character(len=1024) :: expression
107 real(real64),
allocatable :: val(:)
108 real(real64),
allocatable :: valww(:)
109 type(fft_t) :: fft_handler
124 subroutine tdf_read(f, namespace, function_name, ierr)
125 type(tdf_t),
intent(inout) :: f
126 type(namespace_t),
intent(in) :: namespace
127 character(len=*),
intent(in) :: function_name
128 integer,
intent(out) :: ierr
131 integer :: nrows, i, function_type
132 character(len=1024) :: row_name, filename, function_expression
133 real(real64) :: a0, tau0, t0, tau1
208 if (
parse_block(namespace,
'TDFunctions', blk) /= 0)
then
215 row_loop:
do i = 1, nrows
217 if (trim(row_name) == trim(function_name))
then
225 select case (function_type)
271 type(
tdf_t),
intent(in) :: f
279 type(
tdf_t),
intent(in) :: f
286 real(real64)
pure function
tdf_dt(f)
287 type(
tdf_t),
intent(in) :: f
295 type(
tdf_t),
intent(inout) :: f
310 type(
tdf_t),
intent(in) :: f
322 type(
tdf_t),
intent(inout) :: f
323 real(real64),
intent(in) :: a0, omega0
338 type(
tdf_t),
intent(inout) :: f
339 real(real64),
intent(in) :: a0, omega0, t0, tau0
356 type(
tdf_t),
intent(inout) :: f
357 real(real64),
intent(in) :: a0, omega0, t0, tau0
374 type(
tdf_t),
intent(inout) :: f
375 real(real64),
intent(in) :: a0, omega0, t0, tau0, tau1
393 type(
tdf_t),
intent(inout) :: f
394 character(len=*),
intent(in) :: expression
399 f%expression = trim(expression)
408 type(
tdf_t),
intent(inout) :: f
409 character(len=*),
intent(in) :: filename
410 type(namespace_t),
intent(in) :: namespace
411 integer,
intent(out) :: ierr
413 integer :: iunit, lines, j
414 real(real64) :: dummy
415 real(real64),
allocatable :: t(:), am(:)
422 iunit = io_open(trim(filename), namespace, action=
'read', status=
'old')
425 call io_skip_header(iunit)
428 read(iunit, *, err=100,
end=100) dummy, dummy
433 call io_skip_header(iunit)
436 safe_allocate( t(1:lines))
437 safe_allocate(am(1:lines))
439 read(iunit, *) t(j), am(j)
444 f%final_time = t(lines)
446 call spline_init(f%amplitude)
447 call spline_fit(lines, t, am, f%amplitude, m_zero)
450 safe_deallocate_a(am)
459 type(
tdf_t),
intent(inout) :: f
460 integer,
intent(in) :: niter
461 real(real64),
intent(in) :: dt
462 real(real64),
intent(in) :: omegamax
463 real(real64),
optional,
intent(in) :: initval
464 integer,
optional,
intent(in) :: rep
466 integer :: n(3), optimize_parity(3)
474 safe_allocate(f%val(1:niter+1))
475 if (
present(initval))
then
483 f%final_time = f%dt * f%niter
485 if (omegamax > m_zero)
then
486 bigt = f%final_time - f%init_time
487 f%nfreqs = int(bigt * omegamax / (m_two * m_pi)) + 1
489 f%nfreqs = f%niter/2+1
492 n(1:3) = (/ f%niter, 1, 1 /)
494 optimize_parity(1:3) = -1
495 call fft_init(f%fft_handler, n, 1, fft_real, fftlib_fftw,
optimize, optimize_parity)
497 if (
present(rep))
then
500 safe_allocate(f%valww(1:2*(f%nfreqs-1)+1))
502 safe_deallocate_a(f%val)
514 type(
tdf_t),
intent(in) :: f
515 real(real64),
intent(inout) :: wgrid(:)
525 df = m_two * m_pi / (f%final_time-f%init_time)
530 message(1) =
"Illegal mode in tdf_fourier_grid."
531 call messages_fatal(1)
541 type(
tdf_t),
intent(inout) :: f
544 complex(real64),
allocatable :: tmp(:)
548 safe_allocate(tmp(1:f%niter/2+1))
552 f%val(1) = m_half*(f%val(1)+f%val(f%niter+1))
553 f%val(f%niter+1) = f%val(1)
554 call dfft_forward(f%fft_handler, f%val(1:f%niter), tmp)
555 tmp = tmp * f%dt *
sqrt(m_one/(f%final_time-f%init_time))
557 safe_allocate(f%valww(1:2*(f%nfreqs-1)+1))
558 f%valww(1) = real(tmp(1), real64)
560 f%valww(j) = (
sqrt(m_two)) * real(tmp(j), real64)
562 do j = f%nfreqs+1, 2*f%nfreqs-1
563 f%valww(j) = - (
sqrt(m_two)) * aimag(tmp(j-f%nfreqs+1))
566 safe_deallocate_a(tmp)
567 safe_deallocate_a(f%val)
576 type(
tdf_t),
intent(inout) :: f
579 complex(real64),
allocatable :: tmp(:)
583 safe_allocate(tmp(1:f%niter/2+1))
587 tmp(j) = cmplx((
sqrt(m_two)/m_two)*f%valww(j), -(
sqrt(m_two)/m_two)*f%valww(j+f%nfreqs-1), real64)
589 safe_allocate(f%val(1:f%niter+1))
590 call dfft_backward(f%fft_handler, tmp, f%val(1:f%niter))
591 f%val(f%niter+1) = f%val(1)
592 f%val = f%val * f%niter *
sqrt(m_one/(f%final_time-f%init_time))
595 safe_deallocate_a(tmp)
596 safe_deallocate_a(f%valww)
605 type(
tdf_t),
intent(inout) :: f
612 s = sum(f%valww(2:f%nfreqs))
613 f%valww(2:f%nfreqs) = f%valww(2:f%nfreqs) - s/f%nfreqs
623 type(
tdf_t),
intent(inout) :: f
627 assert(abs(f%valww(1)) <= m_epsilon)
637 type(
tdf_t),
intent(inout) :: f
638 real(real64),
intent(in) ::
values(:)
644 f%val(1:f%niter+1) =
values(1:f%niter+1)
646 f%valww(1:2*f%nfreqs-1) =
values(1:2*f%nfreqs-1)
649 f%valww(2:2*f%nfreqs-1) =
values(1:2*f%nfreqs-2)
658 type(
tdf_t),
intent(inout) :: f
659 integer,
intent(in) :: index
660 real(real64),
intent(in) :: val
670 f%valww(index+1) = val
679 type(
tdf_t),
intent(inout) :: f
680 real(real64),
optional,
intent(in) :: fdotf
682 type(c_ptr) :: random_gen_pointer
684 real(real64) :: fdotf_, nrm
685 real(real64),
allocatable :: e(:)
695 message(1) =
"Illegal value for f%mode in tdf_set_random."
696 call messages_fatal(1)
698 safe_allocate(e(1:n))
700 if (mpi_grp_is_root(mpi_world))
then
701 if (
present(fdotf))
then
707 call loct_ran_init(random_gen_pointer)
710 e(i) = loct_ran_gaussian(random_gen_pointer, m_one)
713 e =
sqrt(fdotf_) * e/ nrm
716 e(1:f%nfreqs-1) = e(1:f%nfreqs-1) - sum(e(1:f%nfreqs-1))/(f%nfreqs-1)
718 e =
sqrt(fdotf_) * e/ nrm
721 call loct_ran_end(random_gen_pointer)
724 call mpi_world%bcast(e(1), n, mpi_double_precision, 0)
735 type(
tdf_t),
intent(inout) :: f
736 integer,
optional,
intent(in) :: niter
737 real(real64),
optional,
intent(in) :: dt
738 real(real64),
optional,
intent(in) :: omegamax
742 real(real64),
allocatable :: val(:)
753 safe_allocate(val(1:niter+1))
759 assert(
present(niter))
761 assert(
present(omegamax))
764 safe_deallocate_a(val)
773 real(real64)
pure function
tdfi(f, i) result(y)
774 type(
tdf_t),
intent(in) :: f
775 integer,
intent(in) :: i
794 real(real64) function
tdft(f, t) result(y)
795 type(
tdf_t),
intent(in) :: f
796 real(real64),
intent(in) :: t
798 real(real64),
allocatable :: timearray(:), valarray(:)
799 real(real64) :: r, fre, fim, tcu
808 y = f%a0 *
cos(f%omega0*t)
812 r =
exp(-(t - f%t0)**2 / (m_two*f%tau0**2))
813 y = f%a0 * r *
cos(f%omega0 * t)
818 if (abs(t - f%t0) <= f%tau0)
then
819 r =
cos((m_pi / 2) * ((t - 2 * f%tau0 - f%t0) / f%tau0))
821 y = f%a0 * r *
cos(f%omega0 * t)
824 if (t > f%t0-f%tau0/m_two-f%tau1 .and. t <= f%t0-f%tau0 / m_two)
then
825 r = (t - (f%t0 - f%tau0/m_two - f%tau1)) / f%tau1
826 else if (t>f%t0-f%tau0/m_two .and. t <= f%t0+f%tau0 / m_two)
then
828 else if (t>f%t0+f%tau0/m_two .and. t <= f%t0+f%tau0 / m_two+f%tau1)
then
829 r = (f%t0 + f%tau0/m_two + f%tau1 - t) / f%tau1
833 y = f%a0 * r *
cos(f%omega0 * t)
836 if (t >= f%init_time .and. t <= f%final_time)
then
837 y = spline_eval(f%amplitude, t)
844 il = int(t/f%dt)+1; iu = il+1
846 safe_allocate(timearray(1:4))
847 safe_allocate(valarray(1:4))
850 timearray = (/ m_zero, f%dt, m_two*f%dt, m_three*f%dt /)
851 valarray = (/ f%val(1), f%val(2), f%val(3), f%val(4) /)
852 elseif (il >= f%niter)
then
853 timearray = (/ (f%niter-3)*f%dt, (f%niter-2)*f%dt, (f%niter-1)*f%dt, f%niter*f%dt /)
854 valarray = (/ f%val(f%niter-2), f%val(f%niter-1), f%val(f%niter), f%val(f%niter+1) /)
856 timearray = (/ (il-2)*f%dt, (il-1)*f%dt, il*f%dt, (il+1)*f%dt /)
857 valarray = (/ f%val(il-1), f%val(il), f%val(il+1), f%val(il+2) /)
860 call interpolate(timearray, valarray, t, y)
862 safe_deallocate_a(valarray)
863 safe_deallocate_a(timearray)
866 tcu = units_from_atomic(units_inp%time, t)
867 call parse_expression(fre, fim,
't', tcu, f%expression)
881 type(
tdf_t),
intent(inout) :: f
887 call spline_end(f%amplitude)
889 call fft_end(f%fft_handler)
891 safe_deallocate_a(f%valww)
892 call fft_end(f%fft_handler)
895 safe_deallocate_a(f%val)
904 type(
tdf_t),
intent(inout) :: fout
905 type(
tdf_t),
intent(in) :: fin
919 fout%omega0 = fin%omega0
920 fout%niter = fin%niter
921 fout%final_time = fin%final_time
922 fout%init_time = fin%init_time
923 fout%expression = fin%expression
924 fout%nfreqs = fin%nfreqs
926 fout%amplitude = fin%amplitude
929 safe_allocate(fout%val(1:fout%niter+1))
931 call fft_copy(fin%fft_handler, fout%fft_handler)
934 safe_allocate(fout%valww(1:2*fout%nfreqs-1))
935 fout%valww = fin%valww
936 call fft_copy(fin%fft_handler, fout%fft_handler)
947 real(real64),
intent(in) :: alpha
948 type(
tdf_t),
intent(inout) :: f
958 f%valww = alpha*f%valww
960 call spline_times(alpha, f%amplitude, m_zero)
970 real(real64),
intent(in) :: omega
971 type(
tdf_t),
intent(inout) :: f
981 do j = 1, f%niter + 1
982 t = f%init_time + (j-1)*f%dt
983 f%val(j) = f%val(j) *
cos(omega*t)
992 subroutine tdf_write(f, iunit, namespace)
993 type(
tdf_t),
intent(in) :: f
994 integer,
optional,
intent(in) :: iunit
995 type(namespace_t),
optional,
intent(in) :: namespace
1001 select case (f%mode)
1003 write(message(1),
'(6x,a)')
'Mode: continuous wave.'
1004 write(message(2),
'(6x,a,f10.4,a)')
'Amplitude: ', f%a0,
' [a.u]'
1007 write(message(1),
'(6x,a)')
'Mode: Gaussian envelope.'
1008 write(message(2),
'(6x,a,f10.4,a)')
'Amplitude: ', f%a0,
' [a.u]'
1009 write(message(3),
'(6x,a,f10.4,3a)')
'Width: ', units_from_atomic(units_out%time, f%tau0), &
1010 ' [', trim(units_abbrev(units_out%time)),
']'
1011 write(message(4),
'(6x,a,f10.4,3a)')
'Middle t: ', units_from_atomic(units_out%time, f%t0), &
1012 ' [', trim(units_abbrev(units_out%time)),
']'
1015 write(message(1),
'(6x,a)')
'Mode: cosinoidal envelope.'
1016 write(message(2),
'(6x,a,f10.4,a)')
'Amplitude: ', f%a0,
' [a.u]'
1017 write(message(3),
'(6x,a,f10.4,3a)')
'Width: ', units_from_atomic(units_out%time, f%tau0), &
1018 ' [', trim(units_abbrev(units_out%time)),
']'
1019 write(message(4),
'(6x,a,f10.4,3a)')
'Middle t: ', units_from_atomic(units_out%time, f%t0), &
1020 ' [', trim(units_abbrev(units_out%time)),
']'
1023 write(message(1),
'(6x,a)')
'Mode: trapezoidal envelope.'
1024 write(message(2),
'(6x,a,f10.4,a)')
'Amplitude: ', f%a0,
' [a.u]'
1025 write(message(3),
'(6x,a,f10.4,3a)')
'Width: ', units_from_atomic(units_out%time, f%tau0), &
1026 ' [', trim(units_abbrev(units_out%time)),
']'
1027 write(message(4),
'(6x,a,f10.4,3a)')
'Middle t: ', units_from_atomic(units_out%time, f%t0), &
1028 ' [', trim(units_abbrev(units_out%time)),
']'
1029 write(message(5),
'(6x,a,f10.4,3a)')
'Ramp time: ', units_from_atomic(units_out%time, f%tau1), &
1030 ' [', trim(units_abbrev(units_out%time)),
']'
1033 write(message(1),
'(6x,a)')
'Mode: time-dependent function read from file.'
1036 write(message(1),
'(6x,a)')
'Mode: time-dependent function stored in a numerical array.'
1039 write(message(1),
'(6x,a)')
'Mode: time-dependent function parsed from the expression:'
1040 write(message(2),
'(6x,a)')
' f(t) = '//trim(f%expression)
1044 if (abs(f%omega0) > m_epsilon)
then
1046 write(message(n_msg),
'(6x,a,f10.4,3a)')
'Frequency: ', units_from_atomic(units_out%energy, f%omega0), &
1047 ' [', trim(units_abbrev(units_out%energy)),
']'
1050 call messages_info(n_msg, iunit=iunit, namespace=namespace)
1064 type(
tdf_t),
intent(in) :: f, g
1074 assert(f%mode == g%mode)
1076 select case (f%mode)
1084 fg = fg + f%val(2*i-2+1)*g%val(2*i-2+1) + m_four*f%val(2*i-1+1)*g%val(2*i-1+1) + f%val(2*i+1)*g%val(2*i+1)
1086 fg = fg * f%dt / m_three
1088 if (mod(f%niter, 2).eq.1)
then
1089 fg = fg + m_half * (f%val(f%niter)*g%val(f%niter) + f%val(f%niter+1) * g%val(f%niter+1)) * f%dt
1093 fg = dot_product(f%valww, g%valww)
1095 assert(abs(f%valww(1)) <= m_epsilon)
1096 fg = dot_product(f%valww, g%valww)
1098 do i = 1, f%niter + 1
1100 fg = fg +
tdf(f, i) *
tdf(g, i)
1116 real(real64) function
tdf_diff(f, g) result (fg)
1117 type(
tdf_t),
intent(in) :: f, g
1120 type(
tdf_t) :: fminusg
1125 assert(f%mode == g%mode)
1129 select case (f%mode)
1132 fminusg%val(i) = fminusg%val(i) - g%val(i)
1135 do i = 1, 2*(f%nfreqs-1)+1
1136 fminusg%valww(i) = fminusg%valww(i) - g%valww(i)
1139 message(1) =
"Illegal value for f%mode in tdf_diff"
1140 call messages_fatal(1)
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
real(real64), parameter, public m_zero
This module is intended to contain "only mathematical" functions and procedures.
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public tdf_numerical_to_fourier(f)
integer, parameter, public tdf_from_file
integer, parameter, public tdf_cosinoidal
subroutine, public tdf_init_cw(f, a0, omega0)
integer pure function, public tdf_nfreqs(f)
logical function, public tdf_is_empty(f)
integer, parameter, public tdf_numerical
subroutine tdf_set_numericalr1(f, index, val)
subroutine tdf_set_numericalr(f, values)
subroutine, public tdf_init_fromfile(f, filename, namespace, ierr)
integer pure function, public tdf_niter(f)
integer, parameter, public tdf_empty
subroutine, public tdf_init_cosinoidal(f, a0, omega0, t0, tau0)
subroutine, public tdf_init_gaussian(f, a0, omega0, t0, tau0)
real(real64) pure function tdfi(f, i)
subroutine, public tdf_numerical_to_zerofourier(f)
subroutine, public tdf_end(f)
integer, parameter, public tdf_zero_fourier
subroutine, public tdf_write(f, iunit, namespace)
subroutine, public tdf_copy(fout, fin)
real(real64) function, public tdf_diff(f, g)
subroutine, public tdf_init_trapezoidal(f, a0, omega0, t0, tau0, tau1)
integer, parameter, public tdf_cw
real(real64) function tdft(f, t)
subroutine, public tdf_cosine_multiply(omega, f)
subroutine, public tdf_set_random(f, fdotf)
subroutine, public tdf_fourier_grid(f, wgrid)
integer, parameter, public tdf_trapezoidal
subroutine, public tdf_init(f)
subroutine, public tdf_init_numerical(f, niter, dt, omegamax, initval, rep)
subroutine, public tdf_to_numerical(f, niter, dt, omegamax)
subroutine, public tdf_fourier_to_numerical(f)
subroutine, public tdf_zerofourier_to_numerical(f)
real(real64) function, public tdf_dot_product(f, g)
integer, parameter, public tdf_gaussian
integer, parameter, public tdf_from_expr
subroutine, public tdf_read(f, namespace, function_name, ierr)
This function initializes "f" from the TDFunctions block.
integer, parameter, public tdf_fourier_series
subroutine, public tdf_scalar_multiply(alpha, f)
real(real64) pure function, public tdf_dt(f)
subroutine, public tdf_init_fromexpr(f, expression)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
real(real64) function values(xx)