Octopus
infrared.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
21program infrared
22 use batch_oct_m
24 use debug_oct_m
25 use global_oct_m
26 use io_oct_m
27 use, intrinsic :: iso_fortran_env
30 use parser_oct_m
32 use space_oct_m
34 use unit_oct_m
36
37 implicit none
38
39 integer :: iunit, ierr, ii, jj, iter, read_iter
40 real(real64), allocatable :: dipole(:,:)
41 complex(real64), allocatable :: ftdipole(:,:)
42 type(space_t) :: space
43 real(real64) :: ww, irtotal, dt
44 integer :: ifreq, idir, istart, iend, time_steps, energy_steps, ntiter
45 integer, parameter :: max_freq = 10000
46 type(spectrum_t) :: spectrum
47
48 ! Initialize stuff
50
51 call getopt_init(ierr)
52
53 call getopt_end()
54
55 call parser_init()
56
57 call messages_init()
58
59 call io_init()
61
63
64 call spectrum_init(spectrum, global_namespace, &
65 default_max_energy = units_to_atomic(unit_invcm, 10000.0_real64))
66
68
69 call read_dipole(dipole)
70
71 safe_allocate(ftdipole(1:energy_steps, 1:space%dim))
72 call fourier(dipole, ftdipole)
73
74 !and print the spectrum
75 iunit = io_open('td.general/infrared', global_namespace, action='write')
76
77100 FORMAT(100('#'))
78
79 write(unit = iunit, iostat = ierr, fmt = 100)
80 write(unit = iunit, iostat = ierr, fmt = '(8a)') '# HEADER'
81 write(unit = iunit, iostat = ierr, fmt = '(a25,a1,a1,a10)') &
82 '# all absorptions are in ',units_out%length%abbrev,'*',units_out%time%abbrev
83 write(unit = iunit, iostat = ierr, fmt = '(a1)') '#'
84 write(unit = iunit, iostat = ierr, fmt = '(a19,41x,a17)') '# Energy ', 'absorption'
85 write(unit = iunit, iostat = ierr, fmt = '(a15,13x,a5,15x,a7,13x,a7,13x,a7)') &
86 '# [1/cm]','total','FT(<x>)','FT(<y>)','FT(<z>)'
87 write(unit = iunit, iostat = ierr, fmt = 0100)
88
89 do ifreq = 1, energy_steps
90 ww = (ifreq-1)*spectrum%energy_step + spectrum%min_energy
91 irtotal = norm2(abs(ftdipole(ifreq, 1:3)))
92 write(unit = iunit, iostat = ierr, fmt = '(5e20.10)') &
93 units_from_atomic(unit_invcm, ww), units_from_atomic(units_out%length*units_out%time, ww*irtotal), &
94 (units_from_atomic(units_out%length*units_out%time, ww*abs(ftdipole(ifreq, idir))), idir = 1, 3)
95 end do
96 call io_close(iunit)
97
98 safe_deallocate_a(dipole)
99 safe_deallocate_a(ftdipole)
100
102 call io_end()
103 call messages_end()
104
105 call parser_end()
106 call global_end()
107
108contains
109
110 subroutine read_dipole(dipole)
111 real(real64), allocatable, intent(inout) :: dipole(:, :)
112 character(len=100) :: ioerrmsg
113 real(real64) :: charge, time
115 push_sub(read_dipole)
116
117 ! Opens the coordinates files.
118 iunit = io_open('td.general/multipoles', global_namespace, action='read', status='old', die=.false.)
119 if (iunit < 0) then
120 message(1) = "Cannot open file '"//trim(io_workpath('td.general/multipoles', global_namespace))//"'"
121 call messages_fatal(1)
122 end if
123 call io_skip_header(iunit)
124 call spectrum_count_time_steps(global_namespace, iunit, time_steps, dt)
125 time_steps = time_steps + 1
126
127 ! Find out the iteration numbers corresponding to the time limits.
128 call spectrum_fix_time_limits(spectrum, time_steps, dt, istart, iend, ntiter)
129 istart = max(1, istart)
130 energy_steps = spectrum_nenergy_steps(spectrum)
131
132 safe_allocate(dipole(1:time_steps, 1:space%dim))
133
134 call io_skip_header(iunit)
135
136 do iter = 1, time_steps
137 read(unit = iunit, iostat = ierr, iomsg=ioerrmsg, fmt = *) read_iter, time, &
138 charge, (dipole(iter, idir), idir=1, space%dim)
139
140 !dipole moment has unit of charge*length, charge has the same unit in both systems
141 do ii = 1, space%dim
142 dipole(iter, ii) = units_to_atomic(units_out%length, dipole(iter, ii))
143 end do
144
145 if (ierr /= 0) then
146 exit
147 end if
148 end do
149
150 if (ierr == 0) then
151 write (message(1), '(a)') "Read dipole moment from '"// &
152 trim(io_workpath('td.general/multipoles', global_namespace))//"'."
153 call messages_info(1)
154 else
155 message(1) = "Error reading file '"//trim(io_workpath('td.general/multipoles', global_namespace))//"'"
156 message(2) = ioerrmsg
157 call messages_fatal(2)
158 end if
159
160 call io_close(iunit)
161
162 pop_sub(read_dipole)
163 end subroutine read_dipole
164
165 ! -------------------------------------------------
166 subroutine fourier(fi, ftfi)
167 implicit none
168 real(real64), contiguous, intent(inout) :: fi(:,:)
169 complex(real64), intent(out) :: ftfi(:,:)
170
171 real(real64) :: av
172 integer :: ifreq
173 type(batch_t) :: dipoleb, ftrealb, ftimagb
174 real(real64), allocatable :: ftreal(:,:), ftimag(:,:)
175
176 push_sub(fourier)
177
178 call batch_init(dipoleb, 1, 1, space%dim, fi)
179
180 !apply an envelope
181 call spectrum_signal_damp(spectrum_damp_sin, spectrum%damp_factor, istart, iend, spectrum%start_time, dt, dipoleb)
182
183 !remove the DC component
184 do idir = 1, space%dim
185 av = sum(fi(istart:iend, idir)) / (iend - istart + 1)
186 !$omp parallel do
187 do jj = istart, iend
188 fi(jj, idir) = fi(jj, idir) - av
189 end do
190 end do
191
192 write (message(1), '(a)') "Taking the Fourier transform."
193 call messages_info(1)
194
195 safe_allocate(ftreal(1:energy_steps, 1:space%dim))
196 safe_allocate(ftimag(1:energy_steps, 1:space%dim))
197 call batch_init(ftrealb, 1, 1, space%dim, ftreal)
198 call batch_init(ftimagb, 1, 1, space%dim, ftimag)
199
200 !now calculate the FT
202 istart, iend, spectrum%start_time, dt, dipoleb, spectrum%min_energy, spectrum%max_energy, spectrum%energy_step, ftrealb)
205 istart, iend, spectrum%start_time, dt, dipoleb, spectrum%min_energy, spectrum%max_energy, spectrum%energy_step, ftimagb)
206
207 do idir = 1, space%dim
208 !$omp parallel do
209 do ifreq = 1, energy_steps
210 ftfi(ifreq, idir) = cmplx(ftreal(ifreq, idir), ftimag(ifreq, idir), real64)
211 end do
212 end do
213
214 call dipoleb%end()
215 call ftrealb%end()
216 call ftimagb%end()
217 safe_deallocate_a(ftreal)
218 safe_deallocate_a(ftimag)
219
220 write (message(1), '(a)') "Done."
221 call messages_info(1)
222
223 pop_sub(fourier)
224 end subroutine fourier
225
226end program infrared
227
228!! Local Variables:
229!! mode: f90
230!! coding: utf-8
231!! End:
subroutine read_dipole(dipole)
Definition: infrared.F90:204
program infrared
Definition: infrared.F90:114
subroutine fourier(fi, ftfi)
Definition: infrared.F90:260
initialize a batch with existing memory
Definition: batch.F90:267
This module implements batches of mesh functions.
Definition: batch.F90:133
subroutine, public getopt_init(ierr)
Initializes the getopt machinery. Must be called before attempting to parse the options....
subroutine, public getopt_end
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
Definition: global.F90:381
real(real64), parameter, public m_zero
Definition: global.F90:187
type(mpi_comm), parameter, public serial_dummy_comm
Alias MPI_COMM_UNDEFINED for the specific use case of initialising Octopus utilities with no MPI supp...
Definition: global.F90:264
subroutine, public init_octopus_globals(comm)
Initialise Octopus-specific global constants and files. This routine performs no initialisation calls...
Definition: global.F90:353
Definition: io.F90:114
subroutine, public io_init(defaults)
If the argument defaults is present and set to true, then the routine will not try to read anything f...
Definition: io.F90:166
subroutine, public io_close(iunit, grp)
Definition: io.F90:468
subroutine, public io_skip_header(iunit)
Definition: io.F90:679
subroutine, public io_end()
Definition: io.F90:265
character(len=max_path_len) function, public io_workpath(path, namespace)
Definition: io.F90:313
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:395
subroutine, public messages_end()
Definition: messages.F90:277
subroutine, public messages_init(output_dir)
Definition: messages.F90:224
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
type(namespace_t), public global_namespace
Definition: namespace.F90:132
subroutine, public parser_init()
Initialise the Octopus parser.
Definition: parser.F90:450
subroutine, public parser_end()
End the Octopus parser.
Definition: parser.F90:481
subroutine, public profiling_end(namespace)
Definition: profiling.F90:413
subroutine, public profiling_init(namespace)
Create profiling subdirectory.
Definition: profiling.F90:255
subroutine, public spectrum_fix_time_limits(spectrum, time_steps, dt, istart, iend, ntiter)
Definition: spectrum.F90:2508
subroutine, public spectrum_fourier_transform(method, transform, noise, time_start, time_end, t0, time_step, time_function, energy_start, energy_end, energy_step, energy_function)
Computes the sine, cosine, (or "exponential") Fourier transform of the real function given in the tim...
Definition: spectrum.F90:2638
integer, parameter, public spectrum_damp_sin
Definition: spectrum.F90:164
subroutine, public spectrum_init(spectrum, namespace, default_energy_step, default_max_energy)
Definition: spectrum.F90:213
integer, parameter, public spectrum_fourier
Definition: spectrum.F90:182
subroutine, public spectrum_signal_damp(damp_type, damp_factor, time_start, time_end, t0, time_step, time_function)
Definition: spectrum.F90:2552
integer, parameter, public spectrum_transform_cos
Definition: spectrum.F90:171
integer, parameter, public spectrum_transform_sin
Definition: spectrum.F90:171
subroutine, public spectrum_count_time_steps(namespace, iunit, time_steps, dt)
Definition: spectrum.F90:2386
pure integer function, public spectrum_nenergy_steps(spectrum)
Definition: spectrum.F90:2947
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
This module defines the unit system, used for input and output.
type(unit_t), public unit_invcm
For vibrational frequencies.
type(unit_system_t), public units_out
subroutine, public unit_system_init(namespace)
Class defining batches of mesh functions.
Definition: batch.F90:159