Octopus
phonons_lr.F90
Go to the documentation of this file.
1!! Copyright (C) 2007-2012 Xavier Andrade, David Strubbe
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
23 use debug_oct_m
24 use epot_oct_m
25 use forces_oct_m
26 use global_oct_m
27 use grid_oct_m
29 use io_oct_m
31 use ions_oct_m
32 use, intrinsic :: iso_fortran_env
33 use kdotp_oct_m
38 use math_oct_m
39 use mesh_oct_m
42 use mpi_oct_m
45 use parser_oct_m
49 use smear_oct_m
50 use space_oct_m
57 use unit_oct_m
59 use utils_oct_m
61 use v_ks_oct_m
62
63 implicit none
64
65 private
66 public :: &
72
73contains
74
75 ! ---------------------------------------------------------
76 subroutine phonons_lr_run(system, from_scratch)
77 class(*), intent(inout) :: system
78 logical, intent(in) :: from_scratch
79
80 push_sub(phonons_lr_run)
81
82 select type (system)
83 class is (multisystem_basic_t)
84 message(1) = "CalculationMode = vib_modes not implemented for multi-system calculations"
85 call messages_fatal(1, namespace=system%namespace)
86 type is (electrons_t)
87 call phonons_lr_run_legacy(system, from_scratch)
88 end select
89
90 pop_sub(phonons_lr_run)
91 end subroutine phonons_lr_run
92
93 ! ---------------------------------------------------------
94 subroutine phonons_lr_run_legacy(sys, fromscratch)
95 type(electrons_t), target, intent(inout) :: sys
96 logical, intent(in) :: fromscratch
97
98 type(sternheimer_t) :: sh
99 type(lr_t) :: lr(1:1), kdotp_lr(sys%space%dim)
100 type(vibrations_t) :: vib
101 class(perturbation_ionic_t), pointer :: pert
102
103 type(ions_t), pointer :: ions
104 type(states_elec_t), pointer :: st
105 type(grid_t), pointer :: gr
106
107 integer :: natoms, ndim, iatom, idir, jatom, jdir, imat, jmat, iunit_restart, ierr, start_mode
108 complex(real64), allocatable :: force_deriv(:,:)
109 character(len=80) :: str_tmp
110 character(len=300) :: line(1)
111 type(born_charges_t) :: born
112 logical :: normal_mode_wfs, do_infrared, symmetrize
113 type(restart_t) :: restart_load, restart_dump, kdotp_restart, gs_restart
115 push_sub(phonons_lr_run_legacy)
116
117 !some shortcuts
118
119 ions => sys%ions
120 st => sys%st
121 gr => sys%gr
122
123 if (sys%hm%pcm%run_pcm) then
124 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
125 end if
126
127 if (sys%space%is_periodic()) then
128 call messages_not_implemented('linear-response vib_modes for periodic systems', namespace=sys%namespace)
129 end if
130
131 if (sys%hm%ep%nlcc) then
132 call messages_not_implemented('linear-response vib_modes with non-linear core corrections', namespace=sys%namespace)
133 end if
134
135 !%Variable CalcNormalModeWfs
136 !%Type logical
137 !%Default false
138 !%Section Linear Response::Vibrational Modes
139 !%Description
140 !% If set to true, the response wavefunctions for each normal mode will be calculated
141 !% and written in directory <tt>restart/vib_modes/phn_nm_wfs_XXXXX</tt>.
142 !% This part is time-consuming and not parallel, but not needed for most purposes.
143 !%End
144 call parse_variable(sys%namespace, 'CalcNormalModeWfs', .false., normal_mode_wfs)
145
146 !%Variable CalcInfrared
147 !%Type logical
148 !%Default true
149 !%Section Linear Response::Vibrational Modes
150 !%Description
151 !% If set to true, infrared intensities (and born charges) will be calculated
152 !% and written in <tt>vib_modes/infrared</tt>.
153 !%End
154 call parse_variable(sys%namespace, 'CalcInfrared', .true., do_infrared)
155
156 !%Variable SymmetrizeDynamicalMatrix
157 !%Type logical
158 !%Default true
159 !%Section Linear Response::Vibrational Modes
160 !%Description
161 !% If set to true, all entries of the dynamical matrix will be calculated and then
162 !% the matrix will be symmetrized to enforce <math>D_{ij} = D_{ji}</math>. If set to false,
163 !% only the upper half of the matrix will be calculated.
164 !%End
165 call parse_variable(sys%namespace, 'SymmetrizeDynamicalMatrix', .true., symmetrize)
166
167 ! replaced by properly saving and reading the dynamical matrix
168 call messages_obsolete_variable(sys%namespace, 'UseRestartDontSolve')
170 natoms = ions%natoms
171 ndim = sys%space%dim
172
173 call restart_init(gs_restart, sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=gr, exact=.true.)
174 if (ierr == 0) then
175 call states_elec_look_and_load(gs_restart, sys%namespace, sys%space, st, sys%gr, sys%kpoints)
176 call restart_end(gs_restart)
177 else
178 message(1) = "Previous gs calculation is required."
179 call messages_fatal(1, namespace=sys%namespace)
180 end if
181
182 ! read kdotp wavefunctions if necessary (for IR intensities)
183 if (sys%space%is_periodic() .and. do_infrared) then
184 message(1) = "Reading kdotp wavefunctions for periodic directions."
185 call messages_info(1, namespace=sys%namespace)
186
187 call restart_init(kdotp_restart, sys%namespace, restart_kdotp, restart_type_load, sys%mc, ierr, mesh=gr)
188 if (ierr /= 0) then
189 message(1) = "Unable to read kdotp wavefunctions."
190 message(2) = "Previous kdotp calculation required."
191 call messages_fatal(2, namespace=sys%namespace)
192 end if
193
194 do idir = 1, sys%space%periodic_dim
195 call lr_init(kdotp_lr(idir))
196 call lr_allocate(kdotp_lr(idir), sys%st, sys%gr)
197
198 ! load wavefunctions
199 str_tmp = trim(kdotp_wfs_tag(idir))
200 call restart_open_dir(kdotp_restart, wfs_tag_sigma(sys%namespace, str_tmp, 1), ierr)
201 if (ierr == 0) then
202 call states_elec_load(kdotp_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, ierr, lr=kdotp_lr(idir))
203 end if
204 call restart_close_dir(kdotp_restart)
205
206 if (ierr /= 0) then
207 message(1) = "Unable to read kdotp wavefunctions from '"//trim(wfs_tag_sigma(sys%namespace, str_tmp, 1))//"'."
208 message(2) = "Previous kdotp calculation required."
209 call messages_fatal(2, namespace=sys%namespace)
210 end if
211 end do
212 call restart_end(kdotp_restart)
213 end if
214
215 message(1) = 'Info: Setting up Hamiltonian for linear response.'
216 call messages_info(1, namespace=sys%namespace)
217
218 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
219 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, &
220 wfs_are_cplx = states_are_complex(st))
221
222 call vibrations_init(vib, ions%space, ions%natoms, ions%mass, "lr", sys%namespace)
223
224 call epot_precalc_local_potential(sys%hm%ep, sys%namespace, sys%gr, sys%ions)
225
226 if (do_infrared) then
227 call born_charges_init(born, sys%namespace, ions%natoms, st%val_charge, st%qtot, ndim)
228 end if
229
230 call lr_init(lr(1))
231 call lr_allocate(lr(1), st, gr)
232
233 call restart_init(restart_dump, sys%namespace, restart_vib_modes, restart_type_dump, sys%mc, ierr, mesh=gr)
234 call restart_init(restart_load, sys%namespace, restart_vib_modes, restart_type_load, sys%mc, ierr, mesh=gr)
235
236 !CALCULATE
237
238 ! the ionic contribution, see second term in Eq. 85 in Baroni et al. RMP, 73, 515 (2001)
240
241 ! Compute the -<phi0 | v2 | phi0> term
242 if (states_are_real(st)) then
243 call dionic_pert_matrix_elements_2(sys%gr, sys%namespace, sys%space, sys%ions, sys%hm, 1, st, vib, vib%dyn_matrix)
244 else
245 call zionic_pert_matrix_elements_2(sys%gr, sys%namespace, sys%space, sys%ions, sys%hm, 1, st, vib, vib%dyn_matrix)
246 end if
247
248 if (fromscratch) then
249 start_mode = 1
250 else
251 call phonons_load(restart_load, vib, start_mode)
252 end if
253
254 ! Delete, if fromScratch, or trying to open it failed and there is something wrong with it.
255 if (start_mode == 1) call restart_rm(restart_dump, 'restart')
256
257 ! Output the first start_mode-1 modes
258 do imat = 1, start_mode - 1
259 call vibrations_out_dyn_matrix_row(vib, imat)
260 end do
261
262
263 ! The remaining term is <\psi_1 | v^{(1)} | \psi_0> + <\psi_0 | v^{(1)} | \psi_1>
264 ! We first get \psi_1 from Sternheimer, and then compute the term using X(forces_derivative)
265 ! Note that in order to avoid getting v^{(1)}, we perform an integration by part in this routine
266 pert => perturbation_ionic_t(sys%namespace, ions)
267
268 do imat = start_mode, vib%num_modes
269 iatom = vibrations_get_atom(vib, imat)
270 idir = vibrations_get_dir(vib, imat)
271
272 write(message(1),'(a,i5,a,a1,a)') &
273 "Calculating response to displacement of atom ", iatom, " in ", index2axis(idir), "-direction."
274 call messages_info(1, namespace=sys%namespace)
275
276 ! the converged wfns for the previous mode are probably not a good starting point
277 call lr_zero(lr(1), st)
278
279 if (.not. fromscratch) then
280 message(1) = "Loading restart wavefunctions for linear response."
281 call messages_info(1, namespace=sys%namespace)
282 call restart_open_dir(restart_load, wfs_tag_sigma(sys%namespace, phn_wfs_tag(iatom, idir), 1), ierr)
283 if (ierr == 0) then
284 call states_elec_load(restart_load, sys%namespace, sys%space, st, sys%gr, sys%kpoints, ierr, lr = lr(1))
285 end if
286 if (ierr /= 0) then
287 message(1) = "Unable to read response wavefunctions from '"//&
288 trim(wfs_tag_sigma(sys%namespace, phn_wfs_tag(iatom, idir), 1))//"'."
289 call messages_warning(1, namespace=sys%namespace)
290 end if
291 call restart_close_dir(restart_load)
292 end if
293
294 call pert%setup_atom(iatom)
295 call pert%setup_dir(idir)
296
297 ! We now solve the Sternheimber equation in order to get the first-order change in the wavefunction
298 ! This is then used to get the force derivatives
299 safe_allocate(force_deriv(1:ndim, 1:natoms))
300 if (states_are_real(st)) then
301
302 call dsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
303 lr, 1, m_zero, pert, restart_dump, phn_rho_tag(iatom, idir), phn_wfs_tag(iatom, idir))
304
305 call dforces_derivative(gr, sys%namespace, sys%space, ions, sys%hm%ep, st, sys%kpoints, lr(1), lr(1), force_deriv, &
306 sys%hm%lda_u_level)
307
308 else
309
310 call zsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
311 lr, 1, m_z0, pert, restart_dump, phn_rho_tag(iatom, idir), phn_wfs_tag(iatom, idir))
312
313 call zforces_derivative(gr, sys%namespace, sys%space, ions, sys%hm%ep, st, sys%kpoints, lr(1), lr(1), force_deriv, &
314 sys%hm%lda_u_level)
315
316 end if
317
318 do jmat = 1, vib%num_modes
319 if (.not. symmetrize .and. jmat < imat) then
320 vib%dyn_matrix(jmat, imat) = vib%dyn_matrix(imat, jmat)
321 cycle
322 end if
323
324 jatom = vibrations_get_atom(vib, jmat)
325 jdir = vibrations_get_dir(vib, jmat)
326
327 vib%dyn_matrix(jmat, imat) = vib%dyn_matrix(jmat, imat) + real(force_deriv(jdir, jatom), real64)
328 vib%dyn_matrix(jmat, imat) = vib%dyn_matrix(jmat, imat) * vibrations_norm_factor(vib, iatom, jatom)
329 end do
330 safe_deallocate_a(force_deriv)
331
332 call vibrations_out_dyn_matrix_row(vib, imat)
333
334 if (do_infrared) then
335 if (states_are_real(st)) then
336 call dphonons_lr_infrared(gr, ions, st, lr(1), kdotp_lr, imat, iatom, idir, vib%infrared)
337 else
338 call zphonons_lr_infrared(gr, ions, st, lr(1), kdotp_lr, imat, iatom, idir, vib%infrared)
339 end if
340 end if
341
342 iunit_restart = restart_open(restart_dump, 'restart', position='append')
343 ! open and close makes sure output is not buffered
344 do jmat = 1, vib%num_modes
345 write(line(1), *) jmat, imat, vib%dyn_matrix(jmat, imat)
346 call restart_write(restart_dump, iunit_restart, line, 1, ierr)
347 if (ierr /= 0) then
348 message(1) = "Could not write restart information."
349 call messages_warning(1, namespace=sys%namespace)
350 end if
351 end do
352 write(line(1), *) imat, (vib%infrared(imat, idir), idir = 1, ndim)
353 call restart_write(restart_dump, iunit_restart, line, 1, ierr)
354 if (ierr /= 0) then
355 message(1) = "Could not write restart information."
356 call messages_warning(1, namespace=sys%namespace)
357 end if
358 call restart_close(restart_dump, iunit_restart)
359
360 message(1) = ""
361 call messages_info(1, namespace=sys%namespace)
362 end do
363
364 safe_deallocate_p(pert)
365
366 if (symmetrize) call vibrations_symmetrize_dyn_matrix(vib)
368 call vibrations_output(vib)
369 call axsf_mode_output(vib, ions, gr, sys%namespace)
370
371 if (do_infrared) then
372 if (sys%space%is_periodic() .and. .not. smear_is_semiconducting(st%smear)) then
373 message(1) = "Cannot calculate infrared intensities for periodic system with smearing (i.e. without a gap)."
374 call messages_info(1, namespace=sys%namespace)
375 else
376 call born_from_infrared(vib, born)
377 call born_output_charges(born, ions%atom, ions%charge, ions%natoms, sys%namespace, &
378 ndim, vib_modes_dir, write_real = .true.)
379 call calc_infrared()
380 end if
381
382 call born_charges_end(born)
383 end if
384
385 if (normal_mode_wfs) then
386 message(1) = "Calculating response wavefunctions for normal modes."
387 call messages_info(1, namespace=sys%namespace)
388 if (states_are_real(st)) then
389 call dphonons_lr_wavefunctions(lr(1), sys%namespace, sys%space, st, sys%gr, sys%kpoints, vib, restart_load, &
390 restart_dump)
391 else
392 call zphonons_lr_wavefunctions(lr(1), sys%namespace, sys%space, st, sys%gr, sys%kpoints, vib, restart_load, &
393 restart_dump)
394 end if
395 end if
396
397 !DESTRUCT
398
399 call lr_dealloc(lr(1))
400 call vibrations_end(vib)
401 call sternheimer_end(sh)
403 if (sys%space%is_periodic() .and. do_infrared) then
404 do idir = 1, sys%space%periodic_dim
405 call lr_dealloc(kdotp_lr(idir))
406 end do
407 end if
408 call restart_end(restart_load)
409 call restart_end(restart_dump)
410
411 pop_sub(phonons_lr_run_legacy)
412
413 contains
414
415 ! ---------------------------------------------------------
421 subroutine build_ionic_dyn_matrix()
422 real(real64) :: term, weight, xi(1:ndim), dx(1:ndim), r2
423
425
426 assert(.not. ions%space%is_periodic())
427
428 vib%dyn_matrix(:,:) = m_zero
429
430 do iatom = 1, natoms
431 xi = ions%pos(:, iatom)
432
433 do jatom = 1, natoms
434 if(iatom == jatom) cycle
435
436 dx = xi - ions%pos(:, jatom)
437 r2 = dot_product(dx, dx)
438
439 weight = ions%charge(iatom) * ions%charge(jatom) /(sqrt(r2)**3)
440
441 do idir = 1, ndim
442 do jdir = 1, ndim
443
444 term = weight * (ddelta(idir, jdir) - m_three*dx(idir)*dx(jdir)/r2)
445
446 ! The force is given by F_I = Z_I \sum_K Z_K (R_I-R_K)/|R_I-R_K|^3
447 ! There is therefore a diagonal term from the case J=I, with the sum over K
448 vib%dyn_matrix(vibrations_get_index(vib, iatom, jdir), vibrations_get_index(vib, iatom, idir)) = &
449 vib%dyn_matrix(vibrations_get_index(vib, iatom, jdir), vibrations_get_index(vib, iatom, idir)) + term
450
451 vib%dyn_matrix(vibrations_get_index(vib, jatom, jdir), vibrations_get_index(vib, iatom, idir)) = &
452 vib%dyn_matrix(vibrations_get_index(vib, jatom, jdir), vibrations_get_index(vib, iatom, idir)) - term
453 end do
454 end do
455 end do
456 end do
457
459 end subroutine build_ionic_dyn_matrix
460
461 ! ---------------------------------------------------------
463 subroutine calc_infrared()
464
465 integer :: iunit_ir
466 real(real64) :: lir(1:sys%space%dim+1)
467
469
470 iunit_ir = io_open(vib_modes_dir//'infrared', sys%namespace, action='write')
471
472 write(iunit_ir, '(a)', advance = 'no') '# freq ['//trim(units_abbrev(unit_invcm))//']'
473 do idir = 1, ndim
474 write(iunit_ir, '(a14)', advance = 'no') '<' // index2axis(idir) // '> [' // trim(units_abbrev(units_out%length)) // ']'
475 end do
476 write(iunit_ir, '(a14)') 'average [' // trim(units_abbrev(units_out%length)) // ']'
477
478 do iatom = 1, natoms
479 do idir = 1, ndim
480
481 imat = vibrations_get_index(vib, iatom, idir)
482
483 write(iunit_ir, '(f17.8)', advance = 'no') units_from_atomic(unit_invcm, vib%freq(imat))
484 do jdir = 1, ndim
485 lir(jdir) = dot_product(vib%infrared(:, jdir), vib%normal_mode(:, imat))
486 write(iunit_ir, '(f14.5)', advance = 'no') units_from_atomic(units_out%length, lir(jdir))
487 end do
488
489 lir(ndim+1) = norm2(lir(1:ndim))/sqrt(real(ndim, real64) )
490 write(iunit_ir, '(f17.8)') units_from_atomic(units_out%length, lir(ndim + 1))
491 end do
492 end do
493
494 call io_close(iunit_ir)
496 end subroutine calc_infrared
497
498 end subroutine phonons_lr_run_legacy
499
500
501 ! ---------------------------------------------------------
502 subroutine born_from_infrared(vib, born)
503 type(vibrations_t), intent(in) :: vib
504 type(born_charges_t), intent(inout) :: born
505
506 integer :: imat, idir, iatom
507
508 push_sub(born_from_infrared)
509
510 do imat = 1, vib%num_modes
511 idir = vibrations_get_dir(vib, imat)
512 iatom = vibrations_get_atom(vib, imat)
513 born%charge(1:vib%ndim, idir, iatom) = -vib%infrared(imat, 1:vib%ndim)
514 end do
515
516 pop_sub(born_from_infrared)
517 end subroutine born_from_infrared
518
519
520 ! ---------------------------------------------------------
521 character(len=100) function phn_rho_tag(iatom, dir) result(str)
522 integer, intent(in) :: iatom, dir
523
524 push_sub(phn_rho_tag)
525
526 write(str, '(a,i4.4,a,i1)') 'phn_rho_', iatom, '_', dir
527
528 pop_sub(phn_rho_tag)
529
530 end function phn_rho_tag
531
532
533 ! ---------------------------------------------------------
534 character(len=100) function phn_wfs_tag(iatom, dir) result(str)
535 integer, intent(in) :: iatom, dir
536
537 push_sub(phn_wfs_tag)
538
539 write(str, '(a,i4.4,a,a)') "phn_wfs_", iatom, "_", index2axis(dir)
540
541 pop_sub(phn_wfs_tag)
542
543 end function phn_wfs_tag
544
545
546 ! ---------------------------------------------------------
547 character(len=100) function phn_nm_wfs_tag(inm) result(str)
548 integer, intent(in) :: inm
549
550 push_sub(phn_nm_wfs_tag)
551
552 write(str, '(a,i5.5)') "phn_nm_wfs_", inm
553
554 pop_sub(phn_nm_wfs_tag)
555
556 end function phn_nm_wfs_tag
557
558
559 ! ---------------------------------------------------------
561 subroutine axsf_mode_output(this, ions, mesh, namespace)
562 type(vibrations_t), intent(in) :: this
563 type(ions_t), intent(in) :: ions
564 class(mesh_t), intent(in) :: mesh
565 type(namespace_t), intent(in) :: namespace
566
567 integer :: iunit, iatom, idir, imat, jmat
568 real(real64), allocatable :: forces(:,:)
569 character(len=2) :: suffix
570
571 if (.not. mpi_grp_is_root(mpi_world)) return
572
573 push_sub(axsf_mode_output)
574
575 ! for some reason, direct usage of this%suffix gives an odd result
576 suffix = vibrations_get_suffix(this)
577 iunit = io_open(vib_modes_dir//'normal_modes_'//suffix//'.axsf', namespace, action='write')
578
579 write(iunit, '(a,i6)') 'ANIMSTEPS ', this%num_modes
580 safe_allocate(forces(1:ions%space%dim, 1:ions%natoms))
581 do imat = 1, this%num_modes
582 do jmat = 1, this%num_modes
583 iatom = vibrations_get_atom(this, jmat)
584 idir = vibrations_get_dir(this, jmat)
585 forces(idir, iatom) = this%normal_mode(jmat, imat)
586 end do
587 call write_xsf_geometry(iunit, ions%space, ions%latt, ions%pos, ions%atom, mesh, forces = forces, index = imat)
588 end do
589 safe_deallocate_a(forces)
590 call io_close(iunit)
591
592 pop_sub(axsf_mode_output)
593 end subroutine axsf_mode_output
594
595 ! ---------------------------------------------------------
597 subroutine phonons_load(restart, vib, start_mode)
598 type(restart_t), intent(in) :: restart
599 type(vibrations_t), intent(inout) :: vib
600 integer, intent(out) :: start_mode
601
602 integer :: iunit, ierr, imode, jmode, imode_read, jmode_read
603 character(len=120) :: line(1)
604
605 push_sub(phonons_load)
606
607 iunit = restart_open(restart, 'restart')
608 if (iunit > 0) then
609 imode_loop: do imode = 1, vib%num_modes
610 do jmode = 1, vib%num_modes
611 call restart_read(restart, iunit, line, 1, ierr)
612 if (ierr /= 0) exit imode_loop
613 read(line(1), fmt=*, iostat=ierr) jmode_read, imode_read, vib%dyn_matrix(jmode, imode)
614 if (imode_read /= imode) then
615 write(message(1),'(a,i9,a,i9)') "Corruption of restart data: row ", imode, " is labeled as ", imode_read
616 call messages_fatal(1)
617 end if
618 if (jmode_read /= jmode) then
619 write(message(1),'(a,i9,a,i9)') "Corruption of restart data: column ", jmode, " is labeled as ", jmode_read
620 call messages_fatal(1)
621 end if
622 end do
623
624 call restart_read(restart, iunit, line, 1, ierr)
625 if (ierr /= 0) exit
626
627 start_mode = imode + 1
628
629 read(line(1), fmt=*, iostat=ierr) imode_read, vib%infrared(imode, 1:vib%ndim)
630 if (imode_read /= imode) then
631 write(message(1),'(a,i9,a,i9)') "Corruption of restart data: infrared row ", imode, " is labeled as ", imode_read
632 call messages_fatal(1)
633 end if
634 end do imode_loop
635
636 write(message(1),'(a,i9,a,i9)') 'Info: Read saved dynamical-matrix rows for ', &
637 start_mode - 1, ' modes out of ', vib%num_modes
638 call messages_info(1)
639
640 call restart_close(restart, iunit)
641 else
642 start_mode = 1
643
644 message(1) = "Could not open restart file 'restart'. Starting from scratch."
645 call messages_warning(1)
646 end if
647
648 pop_sub(phonons_load)
649 end subroutine phonons_load
650
651#include "complex.F90"
652#include "phonons_lr_inc.F90"
653
654#include "undef.F90"
655
656#include "real.F90"
657#include "phonons_lr_inc.F90"
658
659end module phonons_lr_oct_m
660
661!! Local Variables:
662!! mode: f90
663!! coding: utf-8
664!! End:
subroutine, public born_charges_end(this)
subroutine, public born_output_charges(this, atom, charge, natoms, namespace, dim, dirname, write_real)
subroutine, public born_charges_init(this, namespace, natoms, val_charge, qtot, dim)
subroutine, public epot_precalc_local_potential(ep, namespace, gr, ions)
Definition: epot.F90:581
subroutine, public zforces_derivative(gr, namespace, space, ions, ep, st, kpoints, lr, lr2, force_deriv, lda_u_level)
Definition: forces.F90:1897
subroutine, public dforces_derivative(gr, namespace, space, ions, ep, st, kpoints, lr, lr2, force_deriv, lda_u_level)
Definition: forces.F90:1245
real(real64), parameter, public m_zero
Definition: global.F90:187
character(len= *), parameter, public vib_modes_dir
Definition: global.F90:255
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_three
Definition: global.F90:190
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public write_xsf_geometry(iunit, space, latt, pos, atoms, mesh, forces, index)
for format specification see: http:
Definition: io.F90:114
subroutine, public io_close(iunit, grp)
Definition: io.F90:468
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:395
character(len=100) function, public kdotp_wfs_tag(dir, dir2)
Definition: kdotp_calc.F90:152
subroutine, public lr_zero(lr, st)
subroutine, public lr_allocate(lr, st, mesh, allocate_rho)
subroutine, public lr_init(lr)
subroutine, public lr_dealloc(lr)
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
real(real64) pure function, public ddelta(i, j)
Definition: math.F90:598
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1125
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1057
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
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
Definition: mpi.F90:430
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
This module implements the basic mulsisystem class, a container system for other systems.
subroutine, public zionic_pert_matrix_elements_2(gr, namespace, space, ions, hm, ik, st, vib, matrix)
Computes the second order term.
subroutine, public dionic_pert_matrix_elements_2(gr, namespace, space, ions, hm, ik, st, vib, matrix)
Computes the second order term.
subroutine dphonons_lr_infrared(mesh, ions, st, lr, kdotp_lr, imat, iatom, idir, infrared)
Definition: phonons_lr.F90:967
subroutine zphonons_lr_wavefunctions(lr, namespace, space, st, mesh, kpoints, vib, restart_load, restart_dump)
calculate the wavefunction associated with each normal mode
Definition: phonons_lr.F90:828
subroutine, public phonons_lr_run(system, from_scratch)
Definition: phonons_lr.F90:170
subroutine zphonons_lr_infrared(mesh, ions, st, lr, kdotp_lr, imat, iatom, idir, infrared)
Definition: phonons_lr.F90:788
subroutine born_from_infrared(vib, born)
Definition: phonons_lr.F90:596
character(len=100) function, public phn_nm_wfs_tag(inm)
Definition: phonons_lr.F90:641
subroutine phonons_load(restart, vib, start_mode)
Load restart information for a linear-response phonon calculation.
Definition: phonons_lr.F90:691
subroutine dphonons_lr_wavefunctions(lr, namespace, space, st, mesh, kpoints, vib, restart_load, restart_dump)
calculate the wavefunction associated with each normal mode
subroutine phonons_lr_run_legacy(sys, fromscratch)
Definition: phonons_lr.F90:188
subroutine, public axsf_mode_output(this, ions, mesh, namespace)
output eigenvectors as animated XSF file, one per frame, displacements as forces
Definition: phonons_lr.F90:655
character(len=100) function, public phn_rho_tag(iatom, dir)
Definition: phonons_lr.F90:615
character(len=100) function, public phn_wfs_tag(iatom, dir)
Definition: phonons_lr.F90:628
subroutine, public restart_read(restart, iunit, lines, nlines, ierr)
Definition: restart.F90:933
subroutine, public restart_close(restart, iunit)
Close a file previously opened with restart_open.
Definition: restart.F90:950
integer, parameter, public restart_kdotp
Definition: restart.F90:229
subroutine, public restart_rm(restart, name)
Remove directory or file "name" that is located inside the current restart directory.
Definition: restart.F90:837
integer, parameter, public restart_gs
Definition: restart.F90:229
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:514
integer, parameter, public restart_type_dump
Definition: restart.F90:225
subroutine, public restart_write(restart, iunit, lines, nlines, ierr)
Definition: restart.F90:906
integer, parameter, public restart_vib_modes
Definition: restart.F90:229
integer function, public restart_open(restart, filename, status, position, silent)
Open file "filename" found inside the current restart directory. Depending on the type of restart,...
Definition: restart.F90:859
subroutine, public restart_open_dir(restart, dirname, ierr)
Change the restart directory to dirname, where "dirname" is a subdirectory of the base restart direct...
Definition: restart.F90:770
integer, parameter, public restart_type_load
Definition: restart.F90:225
subroutine, public restart_end(restart)
Definition: restart.F90:720
subroutine, public restart_close_dir(restart)
Change back to the base directory. To be called after restart_open_dir.
Definition: restart.F90:804
logical pure function, public smear_is_semiconducting(this)
Definition: smear.F90:829
pure logical function, public states_are_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_deallocate_wfns(st)
Deallocates 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_look_and_load(restart, namespace, space, st, mesh, kpoints, is_complex, packed)
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, 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...
subroutine, public dsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
character(len=100) function, public wfs_tag_sigma(namespace, base_name, isigma)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
subroutine, public zsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
subroutine, public sternheimer_end(this)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
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
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_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:679
character(len=2) pure function, public vibrations_get_suffix(this)
Definition: vibrations.F90:222
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
integer pure function, public vibrations_get_dir(this, index)
Definition: vibrations.F90:403
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
integer pure function, public vibrations_get_atom(this, index)
Definition: vibrations.F90:394
subroutine calc_infrared()
calculate infrared intensities
Definition: phonons_lr.F90:557
subroutine build_ionic_dyn_matrix()
Computes the ionic contribution to the dynamical matrix.
Definition: phonons_lr.F90:515
Class describing the electron system.
Definition: electrons.F90:214
Describes mesh distribution to nodes.
Definition: mesh.F90:186
Container class for lists of system_oct_m::system_t.
int true(void)