Octopus
static_pol.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#define RESTART_FILE 'dipoles'
21
24 use debug_oct_m
26 use elf_oct_m
28 use global_oct_m
31 use io_oct_m
33 use ions_oct_m
34 use, intrinsic :: iso_fortran_env
35 use lcao_oct_m
38 use mpi_oct_m
41 use parser_oct_m
44 use scf_oct_m
45 use space_oct_m
50 use unit_oct_m
52 use utils_oct_m
53 use v_ks_oct_m
54
55 implicit none
56
57 private
58 public :: &
60
61
62contains
63
64 ! ---------------------------------------------------------
65 subroutine static_pol_run(system, from_scratch)
66 class(*), intent(inout) :: system
67 logical, intent(in) :: from_scratch
68
69 push_sub(static_pol_run)
70
71 select type (system)
72 class is (multisystem_basic_t)
73 message(1) = "CalculationMode = static_pol not implemented for multi-system calculations"
74 call messages_fatal(1, namespace=system%namespace)
75 type is (electrons_t)
76 call static_pol_run_legacy(system, from_scratch)
77 class default
78 assert(.false.)
79 end select
80
81 pop_sub(static_pol_run)
82 end subroutine static_pol_run
83
84 ! ---------------------------------------------------------
85 subroutine static_pol_run_legacy(sys, fromScratch)
86 type(electrons_t), intent(inout) :: sys
87 logical, intent(in) :: fromScratch
88
89 type(scf_t) :: scfv
90 integer :: iunit, ios, i_start, ii, jj, is, isign, ierr, read_count, verbosity, ip, imax
91 real(real64) :: e_field, e_field_saved
92 real(real64), allocatable :: Vpsl_save(:), trrho(:), dipole(:, :, :)
93 real(real64), allocatable :: elf(:,:), lr_elf(:,:), elfd(:,:), lr_elfd(:,:)
94 real(real64), allocatable :: lr_rho(:,:), lr_rho2(:,:), gs_rho(:,:), tmp_rho(:,:)
95 real(real64) :: center_dipole(1:sys%space%dim), diag_dipole(1:sys%space%dim), ionic_dipole(1:sys%space%dim), &
96 print_dipole(1:sys%space%dim)
97 type(born_charges_t) :: born_charges
98 logical :: calc_born, start_density_is_zero_field, write_restart_densities, calc_diagonal, verbose
99 logical :: diagonal_done, center_written, fromScratch_local, field_written
100 character(len=MAX_PATH_LEN) :: fname, dir_name
101 character(len=120) :: line(1)
102 character :: sign_char
103 type(restart_t) :: gs_restart, restart_load, restart_dump
104
105 push_sub(static_pol_run_legacy)
106
107 if (sys%hm%pcm%run_pcm) then
108 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
109 end if
110
111 if (sys%kpoints%use_symmetries) then
112 call messages_experimental("KPoints symmetries with CalculationMode = em_resp", namespace=sys%namespace)
113 end if
114
115 call init_()
116
117 ! load wavefunctions
118 call gs_restart%init(sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=sys%gr, exact=.true.)
119 if (ierr == 0) then
120 call states_elec_load(gs_restart, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
121 fixed_occ=.false., ierr=ierr)
122 end if
123 if (ierr /= 0) then
124 message(1) = "Unable to read wavefunctions."
125 call messages_fatal(1, namespace=sys%namespace)
126 end if
127 call gs_restart%end()
128
129 if (sys%space%is_periodic()) then
130 message(1) = "Electric field cannot be applied to a periodic system (currently)."
131 call messages_fatal(1, namespace=sys%namespace)
132 end if
133
134 ! set up Hamiltonian
135 message(1) = 'Info: Setting up Hamiltonian.'
136 call messages_info(1, namespace=sys%namespace)
137 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, &
138 sys%hm, calc_eigenval = .false.) ! we read them from restart
139
140 ! Allocate the dipole
141 safe_allocate(dipole(1:sys%space%dim, 1:sys%space%dim, 1:2))
142 dipole = m_zero
143
144 i_start = 1
145 center_written = .false.
146 diagonal_done = .false.
147 field_written = .false.
148
149 call restart_dump%init(sys%namespace, restart_em_resp_fd, restart_type_dump, sys%mc, ierr, mesh=sys%gr)
150
151 if (.not. fromscratch) then
152 call restart_load%init(sys%namespace, restart_em_resp_fd, restart_type_load, sys%mc, ierr, mesh=sys%gr)
153 if (ierr == 0) then
154 iunit = restart_load%open(restart_file)
155 else
156 iunit = -1
157 end if
158
159 if (iunit /= -1) then
160 ! Finds out how many dipoles have already been written.
161 rewind(iunit)
162
163 read(iunit, fmt=*, iostat = ios) e_field_saved
164 field_written = (ios == 0)
165
166 read(iunit, fmt=*, iostat = ios) (center_dipole(jj), jj = 1, sys%space%dim)
167 center_written = (ios == 0)
168
169 do ii = 1, sys%space%dim
170 read(iunit, fmt=*, iostat = ios) ((dipole(ii, jj, isign), jj = 1, sys%space%dim), isign = 1, 2)
171 if (ios /= 0) exit
172 i_start = i_start + 1
173 end do
174
175 read(iunit, fmt=*, iostat = ios) (diag_dipole(jj), jj = 1, sys%space%dim)
176 diagonal_done = (ios == 0)
177
178 call restart_load%close(iunit)
179 end if
181 ! if saved dipoles used a different e_field, we cannot use them
182 if (field_written .and. abs(e_field_saved - e_field) > m_epsilon) then
183 message(1) = "Saved dipoles are from a different electric field, cannot use them."
184 call messages_warning(1, namespace=sys%namespace)
185 center_written = .false.
186 diagonal_done = .false.
187 i_start = 1
188 end if
189
190 read_count = (i_start - 1) * 2
191 if (center_written) read_count = read_count + 1
192 if (diagonal_done) read_count = read_count + 1
193 write(message(1),'(a,i5,a)') "Using ", read_count, " dipole(s) from file."
194 call messages_info(1, namespace=sys%namespace)
195 end if
196
197 if (sys%outp%what(option__output__density) .or. &
198 sys%outp%what(option__output__pol_density)) then
199 if (i_start > 2 .and. calc_diagonal) then
200 i_start = 2
201 diagonal_done = .false.
202 !FIXME: take derivatives between yz and z (not y) so can restart from only last (z) calc
203 end if
204 end if
205
206 if (i_start == 1) then
207 ! open new file, erase old data, write e_field
208 iunit = restart_dump%open(restart_file, status='replace')
209 write(line(1), fmt='(e20.12)') e_field
210 call restart_dump%write(iunit, line, 1, ierr)
211 if (ierr /= 0) then
212 message(1) = "Unsuccessful write of electric field."
213 call messages_warning(1, namespace=sys%namespace)
214 end if
215 call restart_dump%close(iunit)
216 center_written = .false.
217 end if
218
219 ! Save local potential
220 safe_allocate(vpsl_save(1:sys%gr%np))
221 vpsl_save = sys%hm%ep%Vpsl
222
223 ! Allocate the trrho to contain the trace of the density.
224 safe_allocate(trrho(1:sys%gr%np))
225 safe_allocate(gs_rho(1:sys%gr%np, 1:sys%st%d%nspin))
226 safe_allocate(tmp_rho(1:sys%gr%np, 1:sys%st%d%nspin))
227 trrho = m_zero
228 gs_rho = m_zero
229
230 call output_init_()
231 call scf_init(scfv, sys%namespace, sys%gr, sys%ions, sys%st, sys%mc, sys%hm, sys%space)
232 call born_charges_init(born_charges, sys%namespace, sys%ions%natoms, sys%st%val_charge, &
233 sys%st%qtot, sys%space%dim)
234
235 ! now calculate the dipole without field
236
237 sys%hm%ep%vpsl(1:sys%gr%np) = vpsl_save(1:sys%gr%np)
238 call sys%hm%update(sys%gr, sys%namespace, sys%space, sys%ext_partners)
239
240 write(message(1), '(a)')
241 write(message(2), '(a)') 'Info: Calculating dipole moment for zero field.'
242 call messages_info(2, namespace=sys%namespace)
243 call scf_run(scfv, sys%namespace, sys%space, sys%mc, sys%gr, sys%ions, sys%ext_partners, sys%st, &
244 sys%ks, sys%hm, verbosity = verbosity)
245
246 gs_rho(1:sys%gr%np, 1:sys%st%d%nspin) = sys%st%rho(1:sys%gr%np, 1:sys%st%d%nspin)
247 trrho = m_zero
248 do is = 1, sys%st%d%spin_channels
249 call lalg_axpy(sys%gr%np, m_one, gs_rho(:, is), trrho)
250 end do
251
252 ! calculate dipole
253 do jj = 1, sys%space%dim
254 center_dipole(jj) = dmf_moment(sys%gr, trrho, jj, 1)
255 end do
256
257 ! Writes the dipole to file
258 if (.not. center_written) then
259 iunit = restart_dump%open(restart_file, position='append')
260 write(line(1), fmt='(6e20.12)') (center_dipole(jj), jj = 1, sys%space%dim)
261 call restart_dump%write(iunit, line, 1, ierr)
262 if (ierr /= 0) then
263 message(1) = "Unsuccessful write of center dipole."
264 call messages_warning(1, namespace=sys%namespace)
265 end if
266 call restart_dump%close(iunit)
267 end if
268
269 if (mpi_world%is_root()) then
270 ionic_dipole(1:sys%space%dim) = sys%ions%dipole()
271 print_dipole(1:sys%space%dim) = center_dipole(1:sys%space%dim) + ionic_dipole(1:sys%space%dim)
272 call output_dipole(print_dipole, sys%space%dim, namespace=sys%namespace)
273 end if
274
275 do ii = i_start, sys%space%dim
276 do isign = 1, 2
277 write(message(1), '(a)')
278 write(message(2), '(a,f6.4,5a)') 'Info: Calculating dipole moment for field ', &
279 units_from_atomic(units_out%force, (-1)**isign * e_field), ' ', &
280 trim(units_abbrev(units_out%force)), ' in the ', index2axis(ii), '-direction.'
281 call messages_info(2, namespace=sys%namespace)
282 ! there would be an extra factor of -1 in here that is for the electronic charge
283 ! except that we treat electrons as positive
284
285 !$omp parallel do
286 do ip = 1, sys%gr%np
287 sys%hm%ep%vpsl(ip) = vpsl_save(ip) + (-1)**isign * sys%gr%x_t(ip, ii) * e_field
288 end do
289 !$omp end parallel do
290 call sys%hm%update(sys%gr, sys%namespace, sys%space, sys%ext_partners)
291
292 if (isign == 1) then
293 sign_char = '+'
294 else
295 sign_char = '-'
296 end if
297
298 write(dir_name,'(a)') "field_"//index2axis(ii)//sign_char
299 fromscratch_local = fromscratch
300
301 if (.not. fromscratch) then
302 call restart_load%open_dir(trim(dir_name), ierr)
303 if (ierr == 0) then
304 call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
305 fixed_occ=.false., ierr=ierr)
306 end if
307 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
308 if (ierr /= 0) fromscratch_local = .true.
309 call restart_load%close_dir()
310 end if
311
312 if (fromscratch_local) then
313 if (start_density_is_zero_field) then
314 sys%st%rho(1:sys%gr%np, 1:sys%st%d%nspin) = gs_rho(1:sys%gr%np, 1:sys%st%d%nspin)
315 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
316 else
317 call lcao_run(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, &
318 sys%hm, lmm_r = scfv%lmm_r)
319 end if
320 end if
321
322 call scf_mix_clear(scfv)
323 call scf_run(scfv, sys%namespace, sys%space, sys%mc, sys%gr, sys%ions, sys%ext_partners, sys%st, &
324 sys%ks, sys%hm, verbosity = verbosity)
325
326 trrho = m_zero
327 do is = 1, sys%st%d%spin_channels
328 call lalg_axpy(sys%gr%np, m_one, sys%st%rho(:, is), trrho)
329 end do
330
331 ! calculate dipole
332 do jj = 1, sys%space%dim
333 dipole(ii, jj, isign) = dmf_moment(sys%gr, trrho, jj, 1)
334 end do
335
336 if (mpi_world%is_root()) then
337 print_dipole(1:sys%space%dim) = dipole(ii, 1:sys%space%dim, isign) + ionic_dipole(1:sys%space%dim)
338 call output_dipole(print_dipole, sys%space%dim, namespace=sys%namespace)
339 end if
340
341 call output_cycle_()
342
343 if (write_restart_densities) then
344 call restart_dump%open_dir(trim(dir_name), ierr)
345 if (ierr == 0) then
346 call states_elec_dump(restart_dump, sys%space, sys%st, sys%gr, sys%kpoints, ierr)
347 end if
348 call restart_dump%close_dir()
349 if (ierr /= 0) then
350 message(1) = 'Unable to write states wavefunctions.'
351 call messages_warning(1, namespace=sys%namespace)
352 end if
353 end if
354 end do
355
356 ! Writes the dipole to file
357 iunit = restart_dump%open(restart_file, position='append')
358 write(line(1), '(6e20.12)') ((dipole(ii, jj, isign), jj = 1, sys%space%dim), isign = 1, 2)
359 call restart_dump%write(iunit, line, 1, ierr)
360 if (ierr /= 0) then
361 message(1) = "Unsuccessful write of dipole."
362 call messages_warning(1, namespace=sys%namespace)
363 end if
364 call restart_dump%close(iunit)
365 end do
366
367 if (.not. diagonal_done .and. calc_diagonal) then
368 write(message(1), '(a)')
369 write(message(2), '(a,f6.4,3a, f6.4, 3a)') 'Info: Calculating dipole moment for field ', &
370 units_from_atomic(units_out%force, e_field), ' ', &
371 trim(units_abbrev(units_out%force)), ' in the '//index2axis(2)//'-direction plus ', &
372 units_from_atomic(units_out%force, e_field), ' ', &
373 trim(units_abbrev(units_out%force)), ' in the '//index2axis(3)//'-direction.'
374 call messages_info(2, namespace=sys%namespace)
375
376 !$omp parallel do
377 do ip = 1, sys%gr%np
378 sys%hm%ep%vpsl(ip) = vpsl_save(ip) &
379 - (sys%gr%x_t(ip, 2) + sys%gr%x_t(ip, 3)) * e_field
380 end do
381 !$omp end parallel do
382 call sys%hm%update(sys%gr, sys%namespace, sys%space, sys%ext_partners)
383
384 if (isign == 1) then
385 sign_char = '+'
386 else
387 sign_char = '-'
388 end if
389
390 fromscratch_local = fromscratch
391
392 if (.not. fromscratch) then
393 call restart_load%open_dir("field_yz+", ierr)
394 if (ierr == 0) then
395 call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
396 fixed_occ=.false., ierr=ierr)
397 end if
398 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
399 if (ierr /= 0) fromscratch_local = .true.
400 call restart_load%close_dir()
401 end if
402
403 if (fromscratch_local) then
404 if (start_density_is_zero_field) then
405 sys%st%rho(1:sys%gr%np, 1:sys%st%d%nspin) = gs_rho(1:sys%gr%np, 1:sys%st%d%nspin)
406 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
407 else
408 call lcao_run(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, &
409 sys%hm, lmm_r = scfv%lmm_r)
410 end if
411 end if
412
413 call scf_mix_clear(scfv)
414 call scf_run(scfv, sys%namespace, sys%space, sys%mc, sys%gr, sys%ions, sys%ext_partners, sys%st, &
415 sys%ks, sys%hm, verbosity = verbosity)
416
417 trrho = m_zero
418 do is = 1, sys%st%d%spin_channels
419 call lalg_axpy(sys%gr%np, m_one, sys%st%rho(:, is), trrho)
420 end do
421
422 ! calculate dipole
423 do jj = 1, sys%space%dim
424 diag_dipole(jj) = dmf_moment(sys%gr, trrho, jj, 1)
425 end do
426
427 if (mpi_world%is_root()) then
428 print_dipole(1:sys%space%dim) = diag_dipole(1:sys%space%dim) + ionic_dipole(1:sys%space%dim)
429 call output_dipole(print_dipole, sys%space%dim, namespace=sys%namespace)
430 end if
431
432 ! Writes the dipole to file
433 iunit = restart_dump%open(restart_file, position='append')
434 write(line(1), fmt='(3e20.12)') (diag_dipole(jj), jj = 1, sys%space%dim)
435 call restart_dump%write(iunit, line, 1, ierr)
436 if (ierr /= 0) then
437 message(1) = "Unsuccessful write of dipole."
438 call messages_warning(1, namespace=sys%namespace)
439 end if
440 call restart_dump%close(iunit)
441
442 if (write_restart_densities) then
443 call restart_dump%open_dir("field_yz+", ierr)
444 if (ierr == 0) then
445 call states_elec_dump(restart_dump, sys%space, sys%st, sys%gr, sys%kpoints, ierr)
446 end if
447 call restart_dump%close_dir()
448 if (ierr /= 0) then
449 message(1) = 'Unable to write states wavefunctions.'
450 call messages_warning(1, namespace=sys%namespace)
451 end if
452 end if
453
454 end if
455
456 if (.not. fromscratch) call restart_load%end()
457 call scf_end(scfv)
458 call output_end_()
459 call born_charges_end(born_charges)
460
461 safe_deallocate_a(vpsl_save)
462 safe_deallocate_a(trrho)
463 safe_deallocate_a(gs_rho)
464 safe_deallocate_a(tmp_rho)
465 safe_deallocate_a(dipole)
466 call end_()
467 pop_sub(static_pol_run_legacy)
468
469 contains
470
471 ! ---------------------------------------------------------
472 subroutine init_()
474
475 call states_elec_allocate_wfns(sys%st, sys%gr)
476
477 call messages_obsolete_variable(sys%namespace, "EMStaticField", "EMStaticElectricField")
478 !%Variable EMStaticElectricField
479 !%Type float
480 !%Default 0.01 a.u.
481 !%Section Linear Response::Static Polarization
482 !%Description
483 !% Magnitude of the static electric field used to calculate the static polarizability,
484 !% if <tt>ResponseMethod = finite_differences</tt>.
485 !%End
486 call parse_variable(sys%namespace, 'EMStaticElectricField', 0.01_real64, e_field, units_inp%force)
487 if (e_field <= m_zero) then
488 write(message(1), '(a,e14.6,a)') "Input: '", e_field, "' is not a valid EMStaticElectricField."
489 message(2) = '(Must have EMStaticElectricField > 0)'
490 call messages_fatal(2, namespace=sys%namespace)
491 end if
492
493 ! variable defined in em_resp
494 call parse_variable(sys%namespace, 'EMCalcbornCharges', .false., calc_born)
495 if (calc_born) call messages_experimental("Calculation of born effective charges", namespace=sys%namespace)
496
497 !%Variable EMStartDensityIsZeroField
498 !%Type logical
499 !%Default true
500 !%Section Linear Response::Static Polarization
501 !%Description
502 !% Use the charge density from the zero-field calculation as the starting density for
503 !% SCF calculations with applied fields. For small fields, this will be fastest.
504 !% If there is trouble converging with larger fields, set to false,
505 !% to initialize the calculation for each field from scratch, as specified by the LCAO variables.
506 !% Only applies if <tt>ResponseMethod = finite_differences</tt>.
507 !%End
508 call parse_variable(sys%namespace, 'EMStartDensityIsZeroField', .true., start_density_is_zero_field)
509
510 !%Variable EMCalcDiagonalField
511 !%Type logical
512 !%Default true
513 !%Section Linear Response::Static Polarization
514 !%Description
515 !% Calculate <i>yz</i>-field for <math>\beta_{xyz}</math> hyperpolarizability, which is sometimes harder to converge.
516 !% Only applies if <tt>ResponseMethod = finite_differences</tt>.
517 !%End
518 call parse_variable(sys%namespace, 'EMCalcDiagonalField', .true., calc_diagonal)
519
520 !%Variable EMWriteRestartDensities
521 !%Type logical
522 !%Default true
523 !%Section Linear Response::Static Polarization
524 !%Description
525 !% Write density after each calculation for restart, rather than just the resulting electronic dipole moment.
526 !% Only applies if <tt>ResponseMethod = finite_differences</tt>. Restarting from calculations at smaller
527 !% fields can be helpful if there are convergence problems.
528 !%End
529 call parse_variable(sys%namespace, 'EMWriteRestartDensities', .true., write_restart_densities)
530
531 !%Variable EMVerbose
532 !%Type logical
533 !%Default false
534 !%Section Linear Response::Static Polarization
535 !%Description
536 !% Write full SCF output.
537 !% Only applies if <tt>ResponseMethod = finite_differences</tt>.
538 !%End
539 call parse_variable(sys%namespace, 'EMVerbose', .false., verbose)
540
541 if (verbose) then
542 verbosity = verb_full
543 else
544 verbosity = verb_compact
545 end if
546
548 end subroutine init_
549
550 ! ---------------------------------------------------------
551 subroutine end_()
552
553 push_sub(end_)
554
555 call states_elec_deallocate_wfns(sys%st)
556
557 pop_sub(end_)
558 end subroutine end_
559
560
561 !-------------------------------------------------------------
562 subroutine output_init_()
563 push_sub(output_init_)
564
565 !allocate memory for what we want to output
566 if (sys%outp%what(option__output__density) .or. &
567 sys%outp%what(option__output__pol_density)) then
568 safe_allocate(lr_rho(1:sys%gr%np, 1:sys%st%d%nspin))
569 safe_allocate(lr_rho2(1:sys%gr%np, 1:sys%st%d%nspin))
570 end if
571
572 if (sys%outp%what(option__output__elf)) then
573 ! if SPIN_POLARIZED or SPINORS, the ELF contains one extra channel: the total ELF
574 imax = 1
575 if (sys%st%d%ispin /= unpolarized) imax = 3
576 safe_allocate( elf(1:sys%gr%np, 1:imax))
577 safe_allocate( lr_elf(1:sys%gr%np, 1:imax))
578 safe_allocate( elfd(1:sys%gr%np, 1:imax))
579 safe_allocate(lr_elfd(1:sys%gr%np, 1:imax))
580 end if
581
582 pop_sub(output_init_)
583 end subroutine output_init_
584
585
586 !-------------------------------------------------------------
587 subroutine output_cycle_()
588 integer :: iatom, ip, ispin2
589 type(unit_t) :: fn_unit
590
591 push_sub(output_cycle_)
592
593 ! BORN CHARGES
594 if (calc_born) then
595 do iatom = 1, sys%ions%natoms
596 if (isign == 1) then
597 ! temporary assignment for use in next cycle when isign == 2
598 born_charges%charge(ii, 1:sys%space%dim, iatom) = sys%ions%tot_force(:, iatom)
599 else
600 born_charges%charge(ii, 1:sys%space%dim, iatom) = &
601 (sys%ions%tot_force(:, iatom) - born_charges%charge(ii, 1:sys%space%dim, iatom)) &
602 / (m_two*e_field)
603 born_charges%charge(ii, ii, iatom) = born_charges%charge(ii, ii, iatom) + sys%ions%charge(iatom)
604 ! since the efield is applied in the SCF calculation by just altering the external potential felt by the electrons,
605 ! the ionic force due to the efield is not included in the forces returned by the SCF run, and so the ionic
606 ! contribution to the born charge must be added by hand here
607 end if
608 end do
609 end if
610
611 !DENSITY AND POLARIZABILITY DENSITY
612 if (sys%outp%what(option__output__density) .or. &
613 sys%outp%what(option__output__pol_density)) then
614
615 if (isign == 1 .and. ii == 2) then
616 tmp_rho(1:sys%gr%np, 1:sys%st%d%nspin) = sys%st%rho(1:sys%gr%np, 1:sys%st%d%nspin)
617 ! for use in off-diagonal non-linear densities
618 end if
619
620 if (isign == 1) then
621 ! temporary assignment for use in next cycle when isign == 2
622 lr_rho(1:sys%gr%np, 1:sys%st%d%nspin) = sys%st%rho(1:sys%gr%np, 1:sys%st%d%nspin)
623 else
624 !$omp parallel private(ispin2, ip)
625 do ispin2 = 1, sys%st%d%nspin
626 !$omp do
627 do ip = 1, sys%gr%np
628 lr_rho2(ip, ispin2) = &
629 -(sys%st%rho(ip, ispin2) + lr_rho(ip, ispin2) - &
630 2 * gs_rho(ip, ispin2)) / e_field**2
631 end do
632 end do
633 do ispin2 = 1, sys%st%d%nspin
634 !$omp do
635 do ip = 1, sys%gr%np
636 lr_rho(ip, ispin2) = &
637 (sys%st%rho(ip, ispin2) - lr_rho(ip, ispin2)) / (m_two*e_field)
638 end do
639 end do
640 !$omp end parallel
641
642 !write
643 do is = 1, sys%st%d%nspin
644 if (sys%outp%what(option__output__density)) then
645 fn_unit = units_out%length**(1-sys%space%dim) / units_out%energy
646 write(fname, '(a,i1,2a)') 'fd_density-sp', is, '-', index2axis(ii)
647 call dio_function_output(sys%outp%how(option__output__density), em_resp_fd_dir, trim(fname),&
648 sys%namespace, sys%space, sys%gr, lr_rho(:, is), fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
649
650 ! save the trouble of writing many copies of each density, since ii,jj = jj,ii
651 fn_unit = units_out%length**(2-sys%space%dim) / units_out%energy**2
652 do jj = ii, sys%space%dim
653 write(fname, '(a,i1,4a)') 'fd2_density-sp', is, '-', index2axis(ii), '-', index2axis(jj)
654 call dio_function_output(sys%outp%how(option__output__density), em_resp_fd_dir, trim(fname),&
655 sys%namespace, sys%space, sys%gr, lr_rho2(:, is), fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
656 end do
657 end if
658
659 if (sys%outp%what(option__output__pol_density)) then
660 do jj = ii, sys%space%dim
661 fn_unit = units_out%length**(2-sys%space%dim) / units_out%energy
662 write(fname, '(a,i1,4a)') 'alpha_density-sp', is, '-', index2axis(ii), '-', index2axis(jj)
663 call dio_function_output(sys%outp%how(option__output__pol_density), em_resp_fd_dir, trim(fname), &
664 sys%namespace, sys%space, sys%gr, -sys%gr%x_t(:, jj) * lr_rho(:, is), &
665 fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
666
667 fn_unit = units_out%length**(3-sys%space%dim) / units_out%energy**2
668 write(fname, '(a,i1,6a)') 'beta_density-sp', is, '-', index2axis(ii), &
669 '-', index2axis(ii), '-', index2axis(jj)
670 call dio_function_output(sys%outp%how(option__output__pol_density), em_resp_fd_dir, trim(fname), &
671 sys%namespace, sys%space, sys%gr, -sys%gr%x_t(:, jj) * lr_rho2(:, is), &
672 fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
673 end do
674 end if
675 end do
676
677 end if
678 end if
679
680 !ELF
681 if (sys%outp%what(option__output__elf)) then
683 if (isign == 1) then
684 call elf_calc(sys%space, sys%st, sys%gr, sys%kpoints, elf, elfd)
685 else
686 call elf_calc(sys%space, sys%st, sys%gr, sys%kpoints, lr_elf, lr_elfd)
687
688 !numerical derivative
689 !$omp parallel private(ispin2, ip)
690 do ispin2 = 1, sys%st%d%spin_channels
691 !$omp do
692 do ip = 1, sys%gr%np
693 lr_elf(ip, ispin2) = &
694 ( lr_elf(ip, ispin2) - elf(ip, ispin2)) / (m_two * e_field)
695 end do
696 end do
697 do ispin2 = 1, sys%st%d%spin_channels
698 !$omp do
699 do ip = 1, sys%gr%np
700 lr_elfd(ip, ispin2) = &
701 (lr_elfd(ip, ispin2) - elfd(ip, ispin2)) / (m_two * e_field)
702 end do
703 end do
704 !$omp end parallel
705
706 !write (elf_calc does not define the spinor off-diagonal components)
707 do is = 1, sys%st%d%spin_channels
708 write(fname, '(a,i1,2a)') 'lr_elf-sp', is, '-', index2axis(ii)
709 call dio_function_output(sys%outp%how(option__output__elf), em_resp_fd_dir, trim(fname),&
710 sys%namespace, sys%space, sys%gr, lr_elf(:, is), unit_one, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
711 write(fname, '(a,i1,2a)') 'lr_elf_D-sp', is, '-', index2axis(ii)
712 call dio_function_output(sys%outp%how(option__output__elf), em_resp_fd_dir, trim(fname),&
713 sys%namespace, sys%space, sys%gr, lr_elfd(:, is), unit_one, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
714 end do
715 end if
716
717 end if
718
719 pop_sub(output_cycle_)
720 end subroutine output_cycle_
721
722
723 !-------------------------------------------------------------
724 subroutine output_end_()
725 real(real64) :: alpha(sys%space%dim, sys%space%dim)
726 complex(real64) :: beta(sys%space%dim, sys%space%dim, sys%space%dim)
727 integer :: iunit, idir, ip, ispin2
728 type(unit_t) :: fn_unit
729 real(real64) :: freq_factor(3)
730
731 push_sub(output_end_)
732
733 call io_mkdir(em_resp_fd_dir, sys%namespace)
734
735 if ((sys%outp%what(option__output__density) .or. &
736 sys%outp%what(option__output__pol_density)) .and. calc_diagonal) then
737 !$omp parallel private(ispin2, ip)
738 do ispin2 = 1, sys%st%d%nspin
739 !$omp do
740 do ip = 1, sys%gr%np
741 lr_rho2(ip, ispin2) = &
742 -(sys%st%rho(ip, ispin2) - lr_rho(ip, ispin2) &
743 - tmp_rho(ip, ispin2) + gs_rho(ip, ispin2)) / e_field**2
744 end do
745 end do
746 !$omp end parallel
747
748 do is = 1, sys%st%d%nspin
749 if (sys%outp%what(option__output__density)) then
750 fn_unit = units_out%length**(2-sys%space%dim) / units_out%energy**2
751 write(fname, '(a,i1,a)') 'fd2_density-sp', is, '-y-z'
752 call dio_function_output(sys%outp%how(option__output__density), em_resp_fd_dir, trim(fname),&
753 sys%namespace, sys%space, sys%gr, lr_rho2(:, is), fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
754 end if
755
756 if (sys%outp%what(option__output__pol_density)) then
757 fn_unit = units_out%length**(3-sys%space%dim) / units_out%energy**2
758 write(fname, '(a,i1,a)') 'beta_density-sp', is, '-x-y-z'
759 call dio_function_output(sys%outp%how(option__output__pol_density), em_resp_fd_dir, trim(fname),&
760 sys%namespace, sys%space, sys%gr, -sys%gr%x_t(:, 1) * lr_rho2(:, is), &
761 fn_unit, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
762 end if
763 end do
764 end if
765
766 if (mpi_world%is_root()) then ! output pol file
767 iunit = io_open(em_resp_fd_dir//'alpha', sys%namespace, action='write')
768 write(iunit, '(3a)') '# Polarizability tensor [', trim(units_abbrev(units_out%polarizability)), ']'
769
770 alpha(1:sys%space%dim, 1:sys%space%dim) = (dipole(1:sys%space%dim, 1:sys%space%dim, 1) - &
771 dipole(1:sys%space%dim, 1:sys%space%dim, 2)) / (m_two * e_field)
772
773 beta = m_zero
774
775 do idir = 1, sys%space%dim
776 beta(1:sys%space%dim, idir, idir) = &
777 -(dipole(idir, 1:sys%space%dim, 1) + dipole(idir, 1:sys%space%dim, 2) - &
778 m_two * center_dipole(1:sys%space%dim)) / e_field**2
779 beta(idir, 1:sys%space%dim, idir) = beta(1:sys%space%dim, idir, idir)
780 beta(idir, idir, 1:sys%space%dim) = beta(1:sys%space%dim, idir, idir)
781 end do
782
783 assert(sys%space%dim == 3)
784
785 if (calc_diagonal) then
786 beta(1, 2, 3) = -(diag_dipole(1) - dipole(2, 1, 1) - dipole(3, 1, 1) + center_dipole(1)) / e_field**2
787 else
788 beta(1, 2, 3) = m_zero
789 end if
790
791 beta(2, 3, 1) = beta(1, 2, 3)
792 beta(3, 1, 2) = beta(1, 2, 3)
793 beta(3, 2, 1) = beta(1, 2, 3)
794 beta(1, 3, 2) = beta(1, 2, 3)
795 beta(2, 1, 3) = beta(1, 2, 3)
796
797 call output_tensor(alpha, sys%space%dim, units_out%polarizability, iunit=iunit)
798 call io_close(iunit)
799
800 freq_factor(1:3) = m_zero ! for compatibility with em_resp version
801 if (sys%st%system_grp%is_root()) then
802 call out_hyperpolarizability(sys%gr%box, beta, freq_factor(1:3), .true., em_resp_fd_dir, sys%namespace)
803 end if
804
805 if (calc_born) then
806 call born_output_charges(born_charges, sys%ions%atom, sys%ions%charge, sys%ions%natoms, &
807 sys%namespace, sys%space%dim, em_resp_fd_dir, states_are_real(sys%st))
808 end if
809 end if
810
811 if (sys%outp%what(option__output__density) .or. &
812 sys%outp%what(option__output__pol_density)) then
813 safe_deallocate_a(lr_rho)
814 safe_deallocate_a(lr_rho2)
815 end if
816
817 if (sys%outp%what(option__output__elf)) then
818 safe_deallocate_a(lr_elf)
819 safe_deallocate_a(elf)
820 safe_deallocate_a(lr_elfd)
821 safe_deallocate_a(elfd)
822 end if
823
824 pop_sub(output_end_)
825 end subroutine output_end_
826
827 end subroutine static_pol_run_legacy
828
829end module static_pol_oct_m
830
831!! Local Variables:
832!! mode: f90
833!! coding: utf-8
834!! End:
subroutine init_(fromscratch)
Definition: geom_opt.F90:405
subroutine end_()
Definition: geom_opt.F90:927
constant times a vector plus a vector
Definition: lalg_basic.F90:194
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)
integer, parameter, public unpolarized
Parameters...
subroutine, public elf_calc(space, st, gr, kpoints, elf, de)
(time-dependent) electron localization function, (TD)ELF.
Definition: elf.F90:169
subroutine, public out_hyperpolarizability(box, beta, freq_factor, converged, dirname, namespace)
Ref: David M Bishop, Rev Mod Phys 62, 343 (1990) beta generalized to lack of Kleinman symmetry.
Definition: em_resp.F90:3305
character(len= *), parameter, public em_resp_fd_dir
Definition: global.F90:282
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_one
Definition: global.F90:201
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
subroutine, public lcao_run(namespace, space, gr, ions, ext_partners, st, ks, hm, st_start, lmm_r, known_lower_bound)
Definition: lcao.F90:767
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_moment(mesh, ff, idir, order)
This function calculates the "order" moment of the function ff.
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
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_experimental(name, namespace)
Definition: messages.F90:1040
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:338
This module implements the basic mulsisystem class, a container system for other systems.
integer, parameter, public restart_gs
Definition: restart.F90:156
integer, parameter, public restart_em_resp_fd
Definition: restart.F90:156
integer, parameter, public restart_type_dump
Definition: restart.F90:184
integer, parameter, public restart_type_load
Definition: restart.F90:184
subroutine, public scf_mix_clear(scf)
Definition: scf.F90:607
integer, parameter, public verb_full
Definition: scf.F90:206
integer, parameter, public verb_compact
Definition: scf.F90:206
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:260
subroutine, public scf_end(scf)
Definition: scf.F90:577
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:858
pure logical function, public states_are_real(st)
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...
subroutine, public states_elec_dump(restart, space, st, mesh, kpoints, ierr, iter, lr, verbose)
subroutine static_pol_run_legacy(sys, fromScratch)
Definition: static_pol.F90:181
subroutine, public static_pol_run(system, from_scratch)
Definition: static_pol.F90:161
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
type(unit_t), public unit_one
some special units required for particular quantities
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:120
subroutine, public output_tensor(tensor, ndim, unit, write_average, iunit, namespace)
Definition: utils.F90:251
subroutine, public output_dipole(dipole, ndim, iunit, namespace)
Definition: utils.F90:287
character pure function, public index2axis(idir)
Definition: utils.F90:211
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:666
subroutine output_init_()
Definition: static_pol.F90:658
subroutine output_end_()
Definition: static_pol.F90:820
subroutine output_cycle_()
Definition: static_pol.F90:683
Class describing the electron system.
Definition: electrons.F90:222
Container class for lists of system_oct_m::system_t.
int true(void)