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