Octopus
phonon_modes.F90
Go to the documentation of this file.
1!! Copyright (C) 2024 M. Lueders
2!!
3!! This Source Code Form is subject to the terms of the Mozilla Public
4!! License, v. 2.0. If a copy of the MPL was not distributed with this
5!! file, You can obtain one at https://mozilla.org/MPL/2.0/.
6!!
7#include "global.h"
8
10
12
13 use, intrinsic :: iso_fortran_env
15 use debug_oct_m
16 use global_oct_m
17 use io_oct_m
20 use parser_oct_m
22
23 implicit none
24
25 private
26 public :: &
28
29
34 !
35 type, extends(classical_modes_t) :: phonon_modes_t
36
37 real(real64), allocatable :: alpha(:)
38 integer :: num_super
39
40 contains
41
42 procedure :: init => phonon_modes_init
43 final :: phonon_modes_finalize
44
45 end type phonon_modes_t
46
47contains
48
52 !
53 subroutine phonon_modes_init(this, namespace, dim_space, num_atoms, periodic)
54 class(phonon_modes_t), intent(inout) :: this
55 type(namespace_t), intent(in) :: namespace
56 integer, intent(in) :: dim_space
57 integer, intent(in) :: num_atoms
58 logical, intent(in) :: periodic
59
60 character(len=256) :: filename, version_string
61 character(len=128) :: dummy
62 integer :: iunit
63 integer :: imode, num_modes, file_num_modes, num_zero_modes
64
65 real(real64), parameter :: frequency_default_threshold = 1.0e-3_real64
66 real(real64) :: frequency_threshold
67
68 real(real64) :: eigenvecs(1:dim_space*num_atoms)
69 real(real64) :: alpha, frequency
70
71 push_sub(phonon_modes_init)
72
73 this%dim = dim_space * num_atoms
74 num_modes = 0
75
76 !%Variable PhononModesFile
77 !%Type string
78 !%Section System
79 !%Description
80 !% Filename for the phonon modes file. This file is in plain text with the following format:
81 !% <tt>
82 !% Version: <string> # Version number (currently ignored)
83 !% Nmodes: <integer> # Number of modes in the file
84 !% Np: <integer> # Number of primitive cells in the supercell, used to generate the modes
85 !% # Comment line
86 !% frequency: <float> # Frequency of first mode (in atomic units)
87 !% <float> <float> <float> # Normal mode eigenvector (for first atom)
88 !% <float> <float> <float> # Normal mode eigenvector (for second atom)
89 !% ... # repeated for all atoms in the unit cell
90 !% frequency: <float> # Frequency of second mode
91 !% ...
92 !% </tt>
93 !% Note that the order of atoms has to be the same as in the input (or geometry) file.
94 !%End
95 call parse_variable(namespace, "PhononModesFile", "NONE", filename)
96
97 !%Variable PhononModesZeroThreshold
98 !%Type float
99 !%Section System
100 !%Description
101 !% Frequency threshold (in atomic units), below which phonon modes should be considered as zero frequency modes,
102 !% such as translations or rotations, and be ignored for the generation of initial displacements.
103 !%End
104 call parse_variable(namespace, "PhononModesZeroThreshold", frequency_default_threshold, frequency_threshold)
105
106 if (trim(filename) /= "NONE") then
107
108 iunit = io_open(filename, action="read")
109
110 read(iunit, *) version_string
111 ! TODO: check whether the version is current.
112
113 read(iunit, *) dummy, file_num_modes
114 if (trim(dummy) /= 'Nmodes:') then
115 message(1) = "Phonon file ("//trim(filename)//") is ill formatted."
116 call messages_fatal(1, namespace=namespace)
117 end if
118
119 read(iunit, *) dummy, this%num_super
120 if (trim(dummy) /= 'Np:') then
121 message(1) = "Phonon file ("//trim(filename)//") is ill formatted."
122 call messages_fatal(1, namespace=namespace)
123 end if
124
125 safe_allocate(this%frequencies(1:file_num_modes))
126 safe_allocate(this%alpha(1:file_num_modes))
127 safe_allocate(this%eigenvectors(1:this%dim, file_num_modes))
128
129 num_zero_modes = 0
131 do imode=1, file_num_modes
132 read(iunit, *) dummy
133 read(iunit, *) dummy, frequency
134 if(trim(dummy) /= 'frequency:') then
135 message(1) = "Phonon file is ill formatted. ("//trim(filename)//")"
136 call messages_fatal(1, namespace=namespace)
137 end if
138 read(iunit, *) eigenvecs(:)
139 if(periodic) then
140 read(iunit, *) dummy, alpha
141 if(trim(dummy) /= 'alpha:') then
142 message(1) = "Phonon file is ill formatted. ("//trim(filename)//")"
143 call messages_fatal(1, namespace=namespace)
144 end if
145 else
146 alpha = 1.0
147 end if
148 if (frequency > frequency_threshold) then
149 num_modes = num_modes + 1
150 this%frequencies(num_modes) = frequency
151 this%eigenvectors(:, num_modes) = eigenvecs(:)
152 this%alpha(num_modes) = alpha
153 else
154 write(message(1), '(A,"Skip zero frequency mode. Omega = ",F15.5)') trim(filename), frequency
155 call messages_info(1, namespace=namespace)
156 num_zero_modes = num_zero_modes + 1
157 end if
158 end do
159
160 this%num_modes = num_modes
161 ! TODO: This should be adjusted for finite systems. Note, however, that we cannot simply add the dim_space rotational
162 ! modes, as molecular symmetries might reduce that.
163
164 if (this%num_modes + num_zero_modes > dim_space*(num_atoms-1)) then
165 message(1) = "The phonon file ("//trim(filename)//") contains too many modes."
166 message(2) = "Most likely the zero frequency modes have not been identified. Try increasing PhononModesZeroThreshold."
167 message(3) = "Note that for molecules with rotational symmetry, this warning might be triggered wrongly."
168 call messages_warning(3, namespace=namespace)
169 end if
170
171
172 call io_close(iunit)
173
174 else
175
176 this%num_modes = 0
177 this%num_super = 1
178
179 end if
180
181
182 pop_sub(phonon_modes_init)
183 end subroutine phonon_modes_init
184
185 subroutine phonon_modes_finalize(this)
186 type(phonon_modes_t), intent(inout) :: this
187
188 push_sub(phonon_modes_finalize)
189
190 safe_deallocate_a(this%alpha)
191
192 this%dim = 0
193 this%num_modes = 0
194
195 pop_sub(phonon_modes_finalize)
196 end subroutine phonon_modes_finalize
197
198end module phonon_modes_oct_m
This module provides a general class for classical modes.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
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_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module provides a class for (classical) phonon modes.
subroutine phonon_modes_finalize(this)
subroutine phonon_modes_init(this, namespace, dim_space, num_atoms, periodic)
Initialize the phonon modes.
This class describes classical modes, which are specified by their frequencies and eigenvectors.
This class describes phonon modes, which are specified by their frequencies and eigenvectors.