Octopus
phonons_fd.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
22 use debug_oct_m
27 use global_oct_m
28 use grid_oct_m
31 use ions_oct_m
32 use, intrinsic :: iso_fortran_env
33 use mesh_oct_m
39 use parser_oct_m
42 use scf_oct_m
43 use space_oct_m
48 use utils_oct_m
49 use v_ks_oct_m
51
52 implicit none
53
54 private
55 public :: phonons_run
56
57contains
58
59 ! ---------------------------------------------------------
60 subroutine phonons_run(system)
61 class(*), intent(inout) :: system
62
63 push_sub(phonons_run)
64
65 select type (system)
66 class is (multisystem_basic_t)
67 message(1) = "CalculationMode = vib_modes not implemented for multi-system calculations"
68 call messages_fatal(1, namespace=system%namespace)
69 type is (electrons_t)
70 call phonons_run_legacy(system)
71 end select
72
73 pop_sub(phonons_run)
74 end subroutine phonons_run
75
76 ! ---------------------------------------------------------
77 subroutine phonons_run_legacy(sys)
78 type(electrons_t), intent(inout) :: sys
79
80 type(vibrations_t) :: vib
81 integer :: ierr
82 type(restart_t) :: gs_restart
83
84 push_sub(phonons_run_legacy)
85
86 if (sys%hm%pcm%run_pcm) then
87 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
88 end if
89
90 ! Why not? The symmetries are computed only for the unperturbed geometry,
91 ! and are not valid when the atoms are displaced.
92 ! FIXME: implement instead use of symmetry over dynamical matrix to make things more efficient.
93 if (sys%st%symmetrize_density .or. sys%kpoints%use_symmetries) then
94 message(1) = "Cannot compute vibrational modes by finite differences when symmetry is being used."
95 message(2) = "Set KPointsUseSymmetries = no and SymmetrizeDensity = no, for gs run and this run."
96 call messages_fatal(2, namespace=sys%namespace)
97 end if
98
99 call states_elec_allocate_wfns(sys%st, sys%gr)
100
101 ! load wavefunctions
102 call restart_init(gs_restart, sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=sys%gr, exact=.true.)
103 if (ierr == 0) then
104 call states_elec_load(gs_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
105 fixed_occ=.false., ierr=ierr)
106 end if
107 if (ierr /= 0) then
108 message(1) = "Unable to read wavefunctions."
109 call messages_fatal(1, namespace=sys%namespace)
110 end if
111 call restart_end(gs_restart)
112
113 ! setup Hamiltonian
114 message(1) = 'Info: Setting up Hamiltonian.'
115 call messages_info(1, namespace=sys%namespace)
116 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
117
118 call vibrations_init(vib, sys%ions%space, sys%ions%natoms, sys%ions%mass, "fd", sys%namespace)
119
120 !%Variable Displacement
121 !%Type float
122 !%Default 0.01 a.u.
123 !%Section Linear Response::Vibrational Modes
124 !%Description
125 !% When calculating phonon properties by finite differences (<tt>CalculationMode = vib_modes,
126 !% ResponseMethod = finite_differences</tt>),
127 !% <tt>Displacement</tt> controls how much the atoms are to be moved in order to calculate the
128 !% dynamical matrix.
129 !%End
130 call parse_variable(sys%namespace, 'Displacement', 0.01_real64, vib%disp, units_inp%length)
131
132 ! calculate dynamical matrix
133 call get_dyn_matrix(sys%gr, sys%namespace, sys%mc, sys%ions, sys%ext_partners, sys%st, sys%ks, &
134 sys%hm, sys%outp, vib, sys%space)
135
136 call vibrations_output(vib)
137
138 call vibrations_end(vib)
139
140 call states_elec_deallocate_wfns(sys%st)
141 pop_sub(phonons_run_legacy)
142
143 end subroutine phonons_run_legacy
144
145 ! ---------------------------------------------------------
147 subroutine get_dyn_matrix(gr, namespace, mc, ions, ext_partners, st, ks, hm, outp, vib, space)
148 type(grid_t), target, intent(inout) :: gr
149 type(namespace_t), intent(in) :: namespace
150 type(multicomm_t), intent(in) :: mc
151 type(ions_t), intent(inout) :: ions
152 type(partner_list_t), intent(in) :: ext_partners
153 type(states_elec_t), intent(inout) :: st
154 type(v_ks_t), intent(inout) :: ks
155 type(hamiltonian_elec_t), intent(inout) :: hm
156 type(output_t), intent(in) :: outp
157 type(vibrations_t), intent(inout) :: vib
158 type(electron_space_t), intent(in) :: space
159
160 type(scf_t) :: scf
161 integer :: iatom, jatom, alpha, beta, imat, jmat
162 real(real64), allocatable :: forces(:, :), forces0(:, :)
163
164 push_sub(get_dyn_matrix)
165
166
167 call scf_init(scf, namespace, gr, ions, st, mc, hm, space)
168 safe_allocate(forces0(1:space%dim, 1:ions%natoms))
169 safe_allocate(forces(1:space%dim, 1:ions%natoms))
170 forces = m_zero
171 forces0 = m_zero
172
173 do iatom = 1, ions%natoms
174 do alpha = 1, space%dim
175 imat = vibrations_get_index(vib, iatom, alpha)
176
177 call messages_new_line()
178 call messages_print_with_emphasis(namespace=namespace)
179 write(message(1), '(a,i5,3a)') 'Info: Moving atom ', iatom, ' in the +', index2axis(alpha), '-direction.'
180 call messages_info(1, namespace=namespace)
181 call messages_print_with_emphasis(namespace=namespace)
182
183 ! move atom iatom in direction alpha by dist
184 ions%pos(alpha, iatom) = ions%pos(alpha, iatom) + vib%disp
185
186 ! first force
187 call run_displacement()
188 forces0(:, :) = ions%tot_force(:, :)
189
190 call messages_new_line()
191 call messages_print_with_emphasis(namespace=namespace)
192 write(message(1), '(a,i5,3a)') 'Info: Moving atom ', iatom, ' in the -', index2axis(alpha), '-direction.'
193 call messages_info(1, namespace=namespace)
194 call messages_print_with_emphasis(namespace=namespace)
195
196 ions%pos(alpha, iatom) = ions%pos(alpha, iatom) - m_two*vib%disp
197
198 ! second force
199 call run_displacement()
200 forces(:, :) = ions%tot_force(:, :)
201
202 ions%pos(alpha, iatom) = ions%pos(alpha, iatom) + vib%disp
203
204 do jatom = 1, ions%natoms
205 do beta = 1, space%dim
206 jmat = vibrations_get_index(vib, jatom, beta)
207 vib%dyn_matrix(jmat, imat) = (forces0(beta, jatom) - forces(beta, jatom)) / (m_two*vib%disp) &
208 * vibrations_norm_factor(vib, iatom, jatom)
209 end do
210 end do
211 call vibrations_out_dyn_matrix_row(vib, imat)
212
213 end do
214 end do
215 safe_deallocate_a(forces0)
216 safe_deallocate_a(forces)
217 call scf_end(scf)
218
221
222 pop_sub(get_dyn_matrix)
223 contains
224
226 !TODO: The same code is called in the GO run mode. This should be combined
227 subroutine run_displacement()
229
230 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st)
231 call density_calc(st, gr, st%rho)
232 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval=.true.)
233 call energy_calc_total(namespace, space, hm, gr, st, ext_partners)
234 call scf_mix_clear(scf)
235 call scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, verbosity = verb_compact)
236
238 end subroutine run_displacement
239
240 end subroutine get_dyn_matrix
241
242end module phonons_fd_oct_m
243
244!! Local Variables:
245!! mode: f90
246!! coding: utf-8
247!! End:
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:612
subroutine, public energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
This subroutine calculates the total energy of the system. Basically, it adds up the KS eigenvalues,...
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
This module defines classes and functions for interaction partners.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:921
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1114
subroutine, public messages_new_line()
Definition: messages.F90:1135
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:161
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:415
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:617
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
This module implements the basic mulsisystem class, a container system for other systems.
this module contains the low-level part of the output system
Definition: output_low.F90:115
subroutine get_dyn_matrix(gr, namespace, mc, ions, ext_partners, st, ks, hm, outp, vib, space)
Computes the second-order force constant from finite differences.
Definition: phonons_fd.F90:241
subroutine phonons_run_legacy(sys)
Definition: phonons_fd.F90:171
subroutine, public phonons_run(system)
Definition: phonons_fd.F90:154
integer, parameter, public restart_gs
Definition: restart.F90:200
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:516
integer, parameter, public restart_type_load
Definition: restart.F90:245
subroutine, public restart_end(restart)
Definition: restart.F90:722
subroutine, public scf_mix_clear(scf)
Definition: scf.F90:577
integer, parameter, public verb_compact
Definition: scf.F90:203
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:254
subroutine, public scf_end(scf)
Definition: scf.F90:547
subroutine, public scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, verbosity, iters_done, restart_dump)
Legacy version of the SCF code.
Definition: scf.F90:833
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, fixed_occ, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
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
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:118
character pure function, public index2axis(idir)
Definition: utils.F90:202
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:744
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:691
real(real64) pure function, public vibrations_norm_factor(this, iatom, jatom)
Definition: vibrations.F90:291
subroutine, public vibrations_diag_dyn_matrix(this)
Diagonalize the dynamical matrix.
Definition: vibrations.F90:350
subroutine, public vibrations_out_dyn_matrix_row(this, imat)
Outputs one row of the dynamical matrix.
Definition: vibrations.F90:303
subroutine, public vibrations_init(this, space, natoms, mass, suffix, namespace)
Definition: vibrations.F90:168
subroutine, public vibrations_symmetrize_dyn_matrix(this)
Symmetrize the dynamical matric, which is real symmetric matrix.
Definition: vibrations.F90:231
integer pure function, public vibrations_get_index(this, iatom, idim)
Definition: vibrations.F90:384
subroutine, public vibrations_output(this)
Outputs the eigenvectors and eigenenergies of the dynamical matrix.
Definition: vibrations.F90:413
subroutine, public vibrations_end(this)
Definition: vibrations.F90:207
subroutine run_displacement()
Runs GS for a given displaced atomic position.
Definition: phonons_fd.F90:321
Extension of space that contains the knowledge of the spin dimension.
Class describing the electron system.
Definition: electrons.F90:218
Container class for lists of system_oct_m::system_t.
output handler class
Definition: output_low.F90:164
some variables used for the SCF cycle
Definition: scf.F90:209
The states_elec_t class contains all electronic wave functions.
int true(void)