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 type(spectrum_t) :: spectrum
46
47 ! Initialize stuff
49
50 call getopt_init(ierr)
51
52 call getopt_end()
53
54 call parser_init()
55
56 call messages_init()
57
58 call io_init()
60
62
63 call spectrum_init(spectrum, global_namespace, &
64 default_max_energy = units_to_atomic(unit_invcm, 10000.0_real64))
65
67
68 call read_dipole(dipole)
69
70 safe_allocate(ftdipole(1:energy_steps, 1:space%dim))
71 call fourier(dipole, ftdipole)
72
73 !and print the spectrum
74 iunit = io_open('td.general/infrared', global_namespace, action='write')
75
76100 FORMAT(100('#'))
77
78 write(unit = iunit, iostat = ierr, fmt = 100)
79 write(unit = iunit, iostat = ierr, fmt = '(8a)') '# HEADER'
80 write(unit = iunit, iostat = ierr, fmt = '(a25,a1,a1,a10)') &
81 '# all absorptions are in ',units_out%length%abbrev,'*',units_out%time%abbrev
82 write(unit = iunit, iostat = ierr, fmt = '(a1)') '#'
83 write(unit = iunit, iostat = ierr, fmt = '(a19,41x,a17)') '# Energy ', 'absorption'
84 write(unit = iunit, iostat = ierr, fmt = '(a15,13x,a5,15x,a7,13x,a7,13x,a7)') &
85 '# [1/cm]','total','FT(<x>)','FT(<y>)','FT(<z>)'
86 write(unit = iunit, iostat = ierr, fmt = 0100)
87
88 do ifreq = 1, energy_steps
89 ww = (ifreq-1)*spectrum%energy_step + spectrum%min_energy
90 irtotal = norm2(abs(ftdipole(ifreq, 1:3)))
91 write(unit = iunit, iostat = ierr, fmt = '(5e20.10)') &
92 units_from_atomic(unit_invcm, ww), units_from_atomic(units_out%length*units_out%time, ww*irtotal), &
93 (units_from_atomic(units_out%length*units_out%time, ww*abs(ftdipole(ifreq, idir))), idir = 1, 3)
94 end do
95 call io_close(iunit)
96
97 safe_deallocate_a(dipole)
98 safe_deallocate_a(ftdipole)
99
101 call io_end()
102 call messages_end()
103
104 call parser_end()
105 call global_end()
106
107contains
108
109 subroutine read_dipole(dipole)
110 real(real64), allocatable, intent(inout) :: dipole(:, :)
111 character(len=100) :: ioerrmsg
112 real(real64) :: charge, time
113
114 push_sub(read_dipole)
115
116 ! Opens the coordinates files.
117 iunit = io_open('td.general/multipoles', global_namespace, action='read', status='old')
118 call io_skip_header(iunit)
119 call spectrum_count_time_steps(global_namespace, iunit, time_steps, dt)
120 time_steps = time_steps + 1
121
122 ! Find out the iteration numbers corresponding to the time limits.
123 call spectrum_fix_time_limits(spectrum, time_steps, dt, istart, iend, ntiter)
124 istart = max(1, istart)
125 energy_steps = spectrum_nenergy_steps(spectrum)
126
127 safe_allocate(dipole(1:time_steps, 1:space%dim))
128
129 call io_skip_header(iunit)
130
131 do iter = 1, time_steps
132 read(unit = iunit, iostat = ierr, iomsg=ioerrmsg, fmt = *) read_iter, time, &
133 charge, (dipole(iter, idir), idir=1, space%dim)
134
135 !dipole moment has unit of charge*length, charge has the same unit in both systems
136 do ii = 1, space%dim
137 dipole(iter, ii) = units_to_atomic(units_out%length, dipole(iter, ii))
138 end do
139
140 if (ierr /= 0) then
141 exit
142 end if
143 end do
144
145 if (ierr == 0) then
146 write (message(1), '(a)') "Read dipole moment from '"// &
147 trim(io_workpath('td.general/multipoles', global_namespace))//"'."
148 call messages_info(1)
149 else
150 message(1) = "Error reading file '"//trim(io_workpath('td.general/multipoles', global_namespace))//"'"
151 message(2) = ioerrmsg
152 call messages_fatal(2)
153 end if
154
155 call io_close(iunit)
156
157 pop_sub(read_dipole)
158 end subroutine read_dipole
159
160 ! -------------------------------------------------
161 subroutine fourier(fi, ftfi)
162 implicit none
163 real(real64), contiguous, intent(inout) :: fi(:,:)
164 complex(real64), intent(out) :: ftfi(:,:)
165
166 real(real64) :: av
167 integer :: ifreq
168 type(batch_t) :: dipoleb, ftrealb, ftimagb
169 real(real64), allocatable :: ftreal(:,:), ftimag(:,:)
170
171 push_sub(fourier)
172
173 call batch_init(dipoleb, 1, 1, space%dim, fi)
174
175 !apply an envelope
176 call spectrum_signal_damp(spectrum_damp_sin, spectrum%damp_factor, istart, iend, spectrum%start_time, dt, dipoleb)
177
178 !remove the DC component
179 do idir = 1, space%dim
180 av = sum(fi(istart:iend, idir)) / (iend - istart + 1)
181 !$omp parallel do
182 do jj = istart, iend
183 fi(jj, idir) = fi(jj, idir) - av
184 end do
185 end do
186
187 write (message(1), '(a)') "Taking the Fourier transform."
188 call messages_info(1)
189
190 safe_allocate(ftreal(1:energy_steps, 1:space%dim))
191 safe_allocate(ftimag(1:energy_steps, 1:space%dim))
192 call batch_init(ftrealb, 1, 1, space%dim, ftreal)
193 call batch_init(ftimagb, 1, 1, space%dim, ftimag)
194
195 !now calculate the FT
197 istart, iend, spectrum%start_time, dt, dipoleb, spectrum%min_energy, spectrum%max_energy, spectrum%energy_step, ftrealb)
198
200 istart, iend, spectrum%start_time, dt, dipoleb, spectrum%min_energy, spectrum%max_energy, spectrum%energy_step, ftimagb)
201
202 do idir = 1, space%dim
203 !$omp parallel do
204 do ifreq = 1, energy_steps
205 ftfi(ifreq, idir) = cmplx(ftreal(ifreq, idir), ftimag(ifreq, idir), real64)
206 end do
207 end do
208
209 call dipoleb%end()
210 call ftrealb%end()
211 call ftimagb%end()
212 safe_deallocate_a(ftreal)
213 safe_deallocate_a(ftimag)
214
215 write (message(1), '(a)') "Done."
216 call messages_info(1)
217
218 pop_sub(fourier)
219 end subroutine fourier
220
221end program infrared
222
223!! Local Variables:
224!! mode: f90
225!! coding: utf-8
226!! End:
subroutine read_dipole(dipole)
Definition: infrared.F90:203
program infrared
Definition: infrared.F90:114
subroutine fourier(fi, ftfi)
Definition: infrared.F90:255
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:382
real(real64), parameter, public m_zero
Definition: global.F90:188
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:265
subroutine, public init_octopus_globals(comm)
Initialise Octopus-specific global constants and files. This routine performs no initialisation calls...
Definition: global.F90:354
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:161
subroutine, public io_close(iunit, grp)
Definition: io.F90:418
subroutine, public io_skip_header(iunit)
Definition: io.F90:597
subroutine, public io_end()
Definition: io.F90:258
character(len=max_path_len) function, public io_workpath(path, namespace)
Definition: io.F90:270
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:352
subroutine, public messages_end()
Definition: messages.F90:277
subroutine, public messages_init(output_dir)
Definition: messages.F90:224
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:414
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
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:2507
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:2637
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:2551
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:2385
pure integer function, public spectrum_nenergy_steps(spectrum)
Definition: spectrum.F90:2946
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