Octopus
td_write.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
21module td_write_oct_m
22 use blas_oct_m
23 use comm_oct_m
25 use debug_oct_m
33 use global_oct_m
34 use grid_oct_m
35 use output_oct_m
44 use io_oct_m
46 use ions_oct_m
47 use kick_oct_m
48 use, intrinsic :: iso_fortran_env
50 use lasers_oct_m
53 use lda_u_oct_m
56 use math_oct_m
59 use mesh_oct_m
62 use mpi_oct_m
67 use parser_oct_m
73 use space_oct_m
83 use types_oct_m
84 use unit_oct_m
86 use utils_oct_m
88 use v_ks_oct_m
90
91 implicit none
92
93 private
94 public :: &
95 td_write_t, &
106
108 integer, parameter, public :: &
109 OUT_MULTIPOLES = 1, &
110 out_angular = 2, &
111 out_spin = 3, &
112 out_populations = 4, &
113 out_coords = 5, &
114 out_acc = 6, &
115 out_laser = 7, &
116 out_energy = 8, &
117 out_proj = 9, &
118 out_magnets = 10, &
119 out_gauge_field = 11, &
120 out_temperature = 12, &
121 out_ftchd = 13, &
122 out_vel = 14, &
123 out_eigs = 15, &
124 out_ion_ch = 16, &
125 out_total_current = 17, &
126 out_partial_charges = 18, &
127 out_kp_proj = 19, &
128 out_floquet = 20, &
129 out_n_ex = 21, &
130 out_separate_coords = 22, &
132 out_separate_forces = 24, &
134 out_tot_m = 26, &
135 out_q = 27, &
136 out_mxll_field = 28, &
137 out_norm_ks = 29, &
138 ! This constant should always equal the last integer above
139 ! as it defines the total numer of output options
140 out_max = 29
141
142
144 ! Entries must be consistent with the ordering above
145 character(len=100) :: td_file_name(OUT_MAX) = [character(100) :: &
146 "NULL", & ! Do not include OUT_MULTIPOLES (extension is a function of state index)
147 "angular", &
148 "spin", &
149 "populations", &
150 "coordinates", &
151 "acceleration", &
152 "NULL", & ! Do not include OUT_LASER
153 "energy", &
154 "projections", &
155 "magnetic_moments", &
156 "gauge_field", &
157 "temperature", &
158 "NULL", & ! Do not include OUT_FTCHD
159 "velocity", &
160 "eigenvalues", &
161 "ion_ch", &
162 "total_current", &
163 "partial_charges", &
164 "projections", &
165 "floquet_bands", &
166 "n_ex", &
167 "onlyCoordinates", &
168 "onlyVelocities", &
169 "onlyForces", &
170 "total_heat_current", &
171 "total_magnetization", &
172 "photons_q", &
173 "maxwell_dipole_field", &
174 "norm_wavefunctions"]
175
176 integer, parameter :: &
177 OUT_DFTU_EFFECTIVE_U = 1, &
178 out_dftu_max = 1
179
180
181 integer, parameter :: &
182 OUT_MAXWELL_TOTAL_E_FIELD = 1, &
188 out_maxwell_energy = 19, &
195
196 integer, parameter, public :: &
197 OUT_MAXWELL_MAX = 25
198
199 integer, parameter :: &
200 MAXWELL_TOTAL_FIELD = 1, &
203
204 integer, parameter :: &
205 maxwell_e_field = 1, &
207
209 type td_write_prop_t
210 type(c_ptr) :: handle
211 type(c_ptr), allocatable :: mult_handles(:)
212 type(mpi_grp_t) :: mpi_grp
213 integer :: hand_start
214 integer :: hand_end
215 logical :: write = .false.
216 logical :: resolve_states = .false.
217 end type td_write_prop_t
218
222 type td_write_t
223 private
224 type(td_write_prop_t), public :: out(out_max)
225 type(td_write_prop_t) :: out_dftu(out_dftu_max)
226
227 integer :: lmax
228 real(real64) :: lmm_r
229 type(states_elec_t) :: gs_st
230 ! calculate the projections(s) onto it.
231 integer :: n_excited_states
232 type(excited_states_t), allocatable :: excited_st(:)
233 integer :: compute_interval
234 type(elec_matrix_elements_t) :: elec_me
235 end type td_write_t
236
237contains
239
240 subroutine td_write_kick(outp, namespace, space, mesh, kick, ions, iter)
241 type(output_t), intent(in) :: outp
242 type(namespace_t), intent(in) :: namespace
243 type(electron_space_t), intent(in) :: space
244 class(mesh_t), intent(in) :: mesh
245 type(kick_t), intent(in) :: kick
246 type(ions_t), intent(in) :: ions
247 integer, intent(in) :: iter
248
249 complex(real64), allocatable :: kick_function(:)
250 character(len=256) :: filename
251 integer :: err
252
253 push_sub(td_write_kick)
254
255 write(filename, '(a,i7.7)') "td.", iter ! name of directory
256 if (outp%what(option__output__delta_perturbation)) then
257 safe_allocate(kick_function(1:mesh%np))
258 call kick_function_get(space, mesh, kick, kick_function, 1)
259 call zio_function_output(outp%how(option__output__delta_perturbation), filename, "kick_function", namespace, &
260 space, mesh, kick_function(:), units_out%energy, err, pos=ions%pos, atoms=ions%atom)
261 safe_deallocate_a(kick_function)
262 end if
263
264 pop_sub(td_write_kick)
265 end subroutine td_write_kick
266
267
277 subroutine td_write_init(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, ks, ions_move, &
278 with_gauge_field, kick, iter, max_iter, dt, mc)
279 type(td_write_t), target, intent(out) :: writ
280 type(namespace_t), intent(in) :: namespace
281 type(electron_space_t), intent(in) :: space
282 type(output_t), intent(inout) :: outp
283 type(grid_t), intent(in) :: gr
284 type(states_elec_t), intent(inout) :: st
285 type(hamiltonian_elec_t), intent(inout) :: hm
286 type(ions_t), intent(in) :: ions
287 type(partner_list_t), intent(in) :: ext_partners
288 type(v_ks_t), intent(inout) :: ks
289 logical, intent(in) :: ions_move
290 logical, intent(in) :: with_gauge_field
291 type(kick_t), intent(in) :: kick
292 integer, intent(in) :: iter
293 integer, intent(in) :: max_iter
294 real(real64), intent(in) :: dt
295 type(multicomm_t), intent(in) :: mc
296
297 real(real64) :: rmin
298 integer :: ierr, first, ii, ist, jj, flags, iout, default, ifile
299 logical :: output_options(max_output_types)
300 integer :: output_interval(0:max_output_types)
301 integer(int64) :: how(0:max_output_types)
302 type(block_t) :: blk
303 character(len=MAX_PATH_LEN) :: filename
305 logical :: resolve_states
306 logical, allocatable :: skip(:)
310 !%Variable TDOutput
311 !%Type block
312 !%Default multipoles + energy (+ others depending on other options)
313 !%Section Time-Dependent::TD Output
314 !%Description
315 !% Defines what should be output during the time-dependent
316 !% simulation. Many of the options can increase the computational
317 !% cost of the simulation, so only use the ones that you need. In
318 !% most cases the default value is enough, as it is adapted to the
319 !% details of the TD run. If the ions are allowed to be moved, additionally
320 !% the geometry and the temperature are output. If a laser is
321 !% included it will output by default.
322 !%
323 !% Note: the output files generated by this option are updated
324 !% every <tt>RestartWriteInterval</tt> steps.
325 !%
326 !% Example:
327 !% <br><br><tt>%TDOutput
328 !% <br>&nbsp;&nbsp;multipoles
329 !% <br>&nbsp;&nbsp;energy
330 !% <br>%<br></tt>
331 !%
332 !%Option multipoles 1
333 !% Outputs the (electric) multipole moments of the density to the file <tt>td.general/multipoles</tt>.
334 !% This is required to, <i>e.g.</i>, calculate optical absorption spectra of finite systems. The
335 !% maximum value of <math>l</math> can be set with the variable <tt>TDMultipoleLmax</tt>.
336 !%Option angular 2
337 !% Outputs the orbital angular momentum of the system to <tt>td.general/angular</tt>.
338 !% This can be used to calculate circular dicrhoism. Not implemented for periodic systems.
339 !% In case of a nonlocal pseudopotential, the gauge used can be specified using
340 !% the variable <tt>MagneticGaugeCorrection</tt>.
341 !%Option spin 3
342 !% (Experimental) Outputs the expectation value of the spin, which can be used to calculate magnetic
343 !% circular dichroism.
344 !%Option populations 4
345 !% (Experimental) Outputs the projection of the time-dependent
346 !% Kohn-Sham Slater determinant onto the ground state (or
347 !% approximations to the excited states) to the file
348 !% <tt>td.general/populations</tt>. Note that the calculation of
349 !% populations is expensive in memory and computer time, so it
350 !% should only be used if it is really needed. See <tt>TDExcitedStatesToProject</tt>.
351 !%Option geometry 5
352 !% If set (and if the atoms are allowed to move), outputs the coordinates, velocities,
353 !% and forces of the atoms to the the file <tt>td.general/coordinates</tt>. On by default if <tt>MoveIons = yes</tt>.
354 !%Option dipole_acceleration 6
355 !% When set, outputs the acceleration of the electronic dipole, calculated from the Ehrenfest theorem,
356 !% in the file <tt>td.general/acceleration</tt>. This file can then be
357 !% processed by the utility <tt>oct-harmonic-spectrum</tt> in order to obtain the harmonic spectrum.
358 !%Option laser 7
359 !% If set, outputs the laser field to the file <tt>td.general/laser</tt>.
360 !% On by default if <tt>TDExternalFields</tt> is set.
361 !%Option energy 8
362 !% If set, <tt>octopus</tt> outputs the different components of the energy
363 !% to the file <tt>td.general/energy</tt>. Will be zero except for every <tt>TDEnergyUpdateIter</tt> iterations.
364 !%Option td_occup 9
365 !% (Experimental) If set, outputs the projections of the
366 !% time-dependent Kohn-Sham wavefunctions onto the static
367 !% (zero-time) wavefunctions to the file
368 !% <tt>td.general/projections.XXX</tt>. Only use this option if
369 !% you really need it, as it might be computationally expensive. See <tt>TDProjStateStart</tt>.
370 !% The output interval of this quantity is controled by the variable <tt>TDOutputComputeInterval</tt>
371 !% In case of states parallelization, all the ground-state states are stored by each task.
372 !%Option local_mag_moments 10
373 !% If set, outputs the local magnetic moments, integrated in sphere centered around each atom.
374 !% The radius of the sphere can be set with <tt>LocalMagneticMomentsSphereRadius</tt>.
375 !%Option gauge_field 11
376 !% If set, outputs the vector gauge field corresponding to a spatially uniform (but time-dependent)
377 !% external electrical potential. This is only useful in a time-dependent periodic run.
378 !% On by default if <tt>GaugeVectorField</tt> is set.
379 !%Option temperature 12
380 !% If set, the ionic temperature at each step is printed. On by default if <tt>MoveIons = yes</tt>.
381 !%Option ftchd 13
382 !% Write Fourier transform of the electron density to the file <tt>ftchd.X</tt>,
383 !% where X depends on the kick (e.g. with sin-shaped perturbation X=sin).
384 !% This is needed for calculating the dynamic structure factor.
385 !% In the case that the kick mode is qbessel, the written quantity is integral over
386 !% density, multiplied by spherical Bessel function times real spherical harmonic.
387 !% On by default if <tt>TDMomentumTransfer</tt> is set.
388 !%Option dipole_velocity 14
389 !% When set, outputs the dipole velocity, calculated from the Ehrenfest theorem,
390 !% in the file <tt>td.general/velocity</tt>. This file can then be
391 !% processed by the utility <tt>oct-harmonic-spectrum</tt> in order to obtain the harmonic spectrum.
392 !%Option eigenvalues 15
393 !% Write the KS eigenvalues.
394 !%Option ionization_channels 16
395 !% Write the multiple-ionization channels using the KS orbital densities as proposed in
396 !% C. Ullrich, Journal of Molecular Structure: THEOCHEM 501, 315 (2000).
397 !%Option total_current 17
398 !% Output the total current (average of the current density over the cell).
399 !%Option partial_charges 18
400 !% Bader and Hirshfeld partial charges. The output file is called 'td.general/partial_charges'.
401 !%Option td_kpoint_occup 19
402 !% Project propagated Kohn-Sham states to the states at t=0 given in the directory
403 !% restart_proj (see %RestartOptions). This is an alternative to the option
404 !% td_occup, with a formating more suitable for k-points and works only in
405 !% k- and/or state parallelization
406 !%Option td_floquet 20
407 !% Compute non-interacting Floquet bandstructure according to further options:
408 !% TDFloquetFrequency, TDFloquetSample, TDFloquetDimension.
409 !% This is done only once per td-run at t=0.
410 !% works only in k- and/or state parallelization
411 !%Option n_excited_el 21
412 !% Output the number of excited electrons, based on the projections
413 !% of the time evolved wave-functions on the ground-state wave-functions.
414 !% The output interval of this quantity is controled by the variable <tt>TDOutputComputeInterval</tt>
415 !% Note that if one sets RecalculateGSDuringEvolution=yes,
416 !% the code will recompute the GS states
417 !% and use them for the computing the number of excited electrons.
418 !% This is useful if ions are moving or if one wants to get the number of excited electrons in the basis
419 !% of the instantaneous eigenvalues of the Hamiltonian (Houston states).
420 !%Option coordinates_sep 22
421 !% Writes geometries in a separate file.
422 !%Option velocities_sep 23
423 !% Writes velocities in a separate file.
424 !%Option forces_sep 24
425 !% Writes forces in a separate file.
426 !%Option total_heat_current 25
427 !% Output the total heat current (average of the heat current density over the cell).
428 !%Option total_magnetization 26
429 !% Writes the total magnetization, where the total magnetization is calculated at the momentum
430 !% defined by <tt>TDMomentumTransfer</tt>.
431 !% This is used to extract the magnon frequency in case of a magnon kick.
432 !%Option photons_q 27
433 !% Writes photons_q in a separate file.
434 !%Option maxwell_field 28
435 !% Writes total electric field (if coupling is in length_geuge) or vector potential
436 !% (if coupling is in velocity_gauge) coming from the interaction with Maxwell systems
437 !% (only if Maxwell-TDDFT coupling is in dipole).
438 !%Option norm_ks_orbitals 29
439 !% Writes the norm of each Kohn-Sham orbital.
440 !% The data is ordered per row as:
441 !% Iteration time (state 1 kpoint 1) (state2 kpoint1) ... (state-Nstates kpoint1) (state1 kpoint2) ... (state-Nstates kpoint-nkpt)
442 !% noting that the kpoint index will also include the spin index for spin-polarised calculations.
443 !%End
444
445 !defaults
446 output_options = .false.
447 output_options(out_multipoles) = .true.
448 output_options(out_energy) = .true.
449 if (ions_move) then
450 output_options(out_coords) = .true.
451 output_options(out_temperature) = .true.
452 end if
453 if (with_gauge_field) output_options(out_gauge_field) = .true.
454 if (list_has_lasers(ext_partners)) output_options(out_laser) = .true.
455 if (kick%qkick_mode /= qkickmode_none) output_options(out_ftchd) = .true.
456
457 call io_function_read_what_how_when(namespace, space, output_options, how, output_interval, &
458 'TDOutput')
459
460 ! Define which files to write
461 do iout = 1, out_max
462 writ%out(iout)%write = output_options(iout)
463 end do
464
465 ! experimental stuff
466 if (writ%out(out_spin)%write) call messages_experimental('TDOutput = spin', namespace=namespace)
467 if (writ%out(out_populations)%write) call messages_experimental('TDOutput = populations', namespace=namespace)
468 if (writ%out(out_proj)%write) call messages_experimental('TDOutput = td_occup', namespace=namespace)
469 if (writ%out(out_ion_ch)%write) call messages_experimental('TDOutput = ionization_channels', namespace=namespace)
470 if (writ%out(out_partial_charges)%write) call messages_experimental('TDOutput = partial_charges', namespace=namespace)
471 if (writ%out(out_kp_proj)%write) call messages_experimental('TDOutput = td_kpoint_occup', namespace=namespace)
472 if (writ%out(out_floquet)%write) call messages_experimental('TDOutput = td_floquet', namespace=namespace)
473 if (writ%out(out_n_ex)%write) call messages_experimental('TDOutput = n_excited_el', namespace=namespace)
474 if (writ%out(out_q)%write) call messages_experimental('TDOutput = photons_q', namespace=namespace)
475 if (writ%out(out_mxll_field)%write) call messages_experimental('TDOutput = maxwell_field', namespace=namespace)
476
477 if (space%is_periodic() .and. writ%out(out_angular)%write) then
478 call messages_not_implemented("TDOutput angular for periodic systems", namespace=namespace)
479 end if
480
481 !See comment in zstates_elec_mpdotp
482 if (space%is_periodic() .and. writ%out(out_populations)%write) then
483 call messages_not_implemented("TDOutput populations for periodic systems", namespace=namespace)
484 end if
485
486 if (writ%out(out_kp_proj)%write.or.writ%out(out_floquet)%write) then
487 ! make sure this is not domain distributed
488 if (gr%np /= gr%np_global) then
489 message(1) = "TDOutput option td_kpoint_occup and td_floquet do not work with domain parallelization"
490 call messages_fatal(1, namespace=namespace)
491 end if
492 end if
493
494 if ((writ%out(out_separate_forces)%write .or. writ%out(out_coords)%write) .and. space%periodic_dim == 1) then
495 call messages_input_error(namespace, 'TDOutput', &
496 'Forces for systems periodic in 1D are not currently implemented and options that output the forces are not allowed.')
497 end if
498
499 ! NTD: The implementation of the option should be really redone properly
500 if (writ%out(out_kp_proj)%write .and. hm%kpoints%nik_skip == 0) then
501 message(1) = "TDOutput option td_kpoint_occup only work with zero-weight k-points at the moment."
502 call messages_fatal(1, namespace=namespace)
503 end if
504
505 !%Variable TDOutputResolveStates
506 !%Type logical
507 !%Default No
508 !%Section Time-Dependent::TD Output
509 !%Description
510 !% Defines whether the output should be resolved by states.
511 !%
512 !% So far only TDOutput = multipoles is supported.
513 !%
514 !%End
515 call parse_variable(namespace, 'TDOutputResolveStates', .false., resolve_states)
516 if (.not. writ%out(out_multipoles)%write) then
517 write(message(1),'(a)') "TDOutputResolveStates works only for TDOutput = multipoles."
518 call messages_warning(1, namespace=namespace)
519 end if
520
521 !%Variable TDMultipoleLmax
522 !%Type integer
523 !%Default 1
524 !%Section Time-Dependent::TD Output
525 !%Description
526 !% Maximum electric multipole of the density output to the file <tt>td.general/multipoles</tt>
527 !% during a time-dependent simulation. Must be non-negative.
528 !%End
529 call parse_variable(namespace, 'TDMultipoleLmax', 1, writ%lmax)
530 if (writ%lmax < 0) then
531 write(message(1), '(a,i6,a)') "Input: '", writ%lmax, "' is not a valid TDMultipoleLmax."
532 message(2) = '(Must be TDMultipoleLmax >= 0 )'
533 call messages_fatal(2, namespace=namespace)
534 end if
535 call messages_obsolete_variable(namespace, 'TDDipoleLmax', 'TDMultipoleLmax')
536
537 ! Compatibility test
538 if ((writ%out(out_acc)%write) .and. ions_move) then
539 message(1) = 'If harmonic spectrum is to be calculated, atoms should not be allowed to move.'
540 call messages_fatal(1, namespace=namespace)
541 end if
542
543 if ((writ%out(out_q)%write) .and. .not.(ks%has_photons)) then
544 message(1) = 'If q(t) is to be calculated, you need to allow for photon modes.'
545 call messages_fatal(1, namespace=namespace)
546 end if
547
548 if ((writ%out(out_mxll_field)%write) .and. .not. (hm%mxll%coupling_mode == velocity_gauge_dipole &
549 .or. hm%mxll%add_electric_dip)) then
550 message(1) = 'If the dipolar field has to be written, MaxwellCouplingMode has to be'
551 message(2) = '"lenght_gauge_dipole" or "velocity_gauge_dipole" and at least one Maxwell system'
552 message(3) = 'must be present.'
553 call messages_fatal(3, namespace=namespace)
554 end if
555
556 rmin = ions%min_distance()
557
558 ! This variable is documented in scf/scf.F90
559 call parse_variable(namespace, 'LocalMagneticMomentsSphereRadius', min(m_half*rmin, lmm_r_single_atom), writ%lmm_r, &
560 unit=units_inp%length)
561
562 if (writ%out(out_proj)%write .or. writ%out(out_populations)%write &
563 .or.writ%out(out_kp_proj)%write .or. writ%out(out_n_ex)%write) then
564
565 if (st%parallel_in_states .and. writ%out(out_populations)%write) then
566 message(1) = "Option TDOutput = populations is not implemented for parallel in states."
567 call messages_fatal(1, namespace=namespace)
568 end if
569
570 if (writ%out(out_proj)%write .or. writ%out(out_populations)%write) then
571 call states_elec_copy(writ%gs_st, st, exclude_wfns = .true., exclude_eigenval = .true.)
572 else
573 ! we want the same layout of gs_st as st
574 call states_elec_copy(writ%gs_st, st, special=.true.)
575 end if
576
577 ! clean up all the stuff we have to reallocate
578 safe_deallocate_a(writ%gs_st%node)
579
580 call restart_init(restart_gs, namespace, restart_proj, restart_type_load, mc, ierr, mesh=gr)
581
582 if (writ%out(out_proj)%write .or. writ%out(out_populations)%write) then
583 if (ierr == 0) then
584 call states_elec_look(restart_gs, ii, jj, writ%gs_st%nst, ierr)
585 end if
586 writ%gs_st%st_end = writ%gs_st%nst
587 if (ierr /= 0) then
588 message(1) = "Unable to read states information."
589 call messages_fatal(1, namespace=namespace)
590 end if
591
592 writ%gs_st%st_start = 1
593 ! do this only when not calculating populations, since all states are needed then
594 if (.not. writ%out(out_populations)%write) then
595 ! We will store the ground-state Kohn-Sham system for all processors.
596 !%Variable TDProjStateStart
597 !%Type integer
598 !%Default 1
599 !%Section Time-Dependent::TD Output
600 !%Description
601 !% To be used with <tt>TDOutput = td_occup</tt>. Not available if <tt>TDOutput = populations</tt>.
602 !% Only output projections to states above <tt>TDProjStateStart</tt>. Usually one is only interested
603 !% in particle-hole projections around the HOMO, so there is no need to calculate (and store)
604 !% the projections of all TD states onto all static states. This sets a lower limit. The upper limit
605 !% is set by the number of states in the propagation and the number of unoccupied states
606 !% available.
607 !%End
608 call parse_variable(namespace, 'TDProjStateStart', 1, writ%gs_st%st_start)
609
610 if (st%parallel_in_states .and. writ%out(out_proj)%write .and. writ%gs_st%st_start > 1) then
611 call messages_not_implemented("TDOutput = td_occup for parallel in states with TDProjStateStart > 1", &
612 namespace=namespace)
613 end if
614 end if
615
616 writ%gs_st%lnst = writ%gs_st%st_end - writ%gs_st%st_start + 1
617
618 call states_elec_deallocate_wfns(writ%gs_st)
619
620 writ%gs_st%parallel_in_states = .false.
621
622 ! allocate memory
623 safe_allocate(writ%gs_st%occ(1:writ%gs_st%nst, 1:writ%gs_st%nik))
624 safe_allocate(writ%gs_st%eigenval(1:writ%gs_st%nst, 1:writ%gs_st%nik))
625
626 !We want all the task to have all the states
627 !States can be distibuted for the states we propagate.
628 safe_allocate(writ%gs_st%node(1:writ%gs_st%nst))
629 writ%gs_st%node(:) = 0
630
631 writ%gs_st%eigenval = huge(writ%gs_st%eigenval)
632 writ%gs_st%occ = m_zero
633 if (writ%gs_st%d%ispin == spinors) then
634 safe_deallocate_a(writ%gs_st%spin)
635 safe_allocate(writ%gs_st%spin(1:3, 1:writ%gs_st%nst, 1:writ%gs_st%nik))
636 end if
637
638 safe_allocate(skip(1:writ%gs_st%nst))
639 skip = .false.
640 skip(1:writ%gs_st%st_start-1) = .true.
641
642 call states_elec_allocate_wfns(writ%gs_st, gr, type_cmplx, packed=.true., skip=skip)
643
644 safe_deallocate_a(skip)
645 end if
646
647 call states_elec_load(restart_gs, namespace, space, writ%gs_st, gr, hm%kpoints, ierr, label = ': gs for TDOutput')
648
649 if (ierr /= 0 .and. ierr /= (writ%gs_st%st_end-writ%gs_st%st_start+1)*writ%gs_st%nik &
650 *writ%gs_st%d%dim*writ%gs_st%mpi_grp%size) then
651 message(1) = "Unable to read wavefunctions for TDOutput."
652 call messages_fatal(1, namespace=namespace)
653 end if
655 end if
656
657 ! Build the excited states...
658 if (writ%out(out_populations)%write) then
659 !%Variable TDExcitedStatesToProject
660 !%Type block
661 !%Section Time-Dependent::TD Output
662 !%Description
663 !% <b>[WARNING: This is a *very* experimental feature]</b>
664 !% To be used with <tt>TDOutput = populations</tt>.
665 !% The population of the excited states
666 !% (as defined by <Phi_I|Phi(t)> where |Phi(t)> is the many-body time-dependent state at
667 !% time <i>t</i>, and |Phi_I> is the excited state of interest) can be approximated -- it is not clear
668 !% how well -- by substituting for those real many-body states the time-dependent Kohn-Sham
669 !% determinant and some modification of the Kohn-Sham ground-state determinant (<i>e.g.</i>,
670 !% a simple HOMO-LUMO substitution, or the Casida ansatz for excited states in linear-response
671 !% theory. If you set <tt>TDOutput</tt> to contain <tt>populations</tt>, you may ask for these approximated
672 !% populations for a number of excited states, which will be described in the files specified
673 !% in this block: each line should be the name of a file that contains one excited state.
674 !%
675 !% This file structure is the one written by the casida run mode, in the files in the directory <tt>*_excitations</tt>.
676 !% The file describes the "promotions" from occupied
677 !% to unoccupied levels that change the initial Slater determinant
678 !% structure specified in ground_state. These promotions are a set
679 !% of electron-hole pairs. Each line in the file, after an optional header, has four
680 !% columns:
681 !%
682 !% <i>i a <math>\sigma</math> weight</i>
683 !%
684 !% where <i>i</i> should be an occupied state, <i>a</i> an unoccupied one, and <math>\sigma</math>
685 !% the spin of the corresponding orbital. This pair is then associated with a
686 !% creation-annihilation pair <math>a^{\dagger}_{a,\sigma} a_{i,\sigma}</math>, so that the
687 !% excited state will be a linear combination in the form:
688 !%
689 !% <math>\left|{\rm ExcitedState}\right> =
690 !% \sum weight(i,a,\sigma) a^{\dagger}_{a,\sigma} a_{i,\sigma} \left|{\rm GroundState}\right></math>
691 !%
692 !% where <i>weight</i> is the number in the fourth column.
693 !% These weights should be normalized to one; otherwise the routine
694 !% will normalize them, and write a warning.
695 !%End
696 if (parse_block(namespace, 'TDExcitedStatesToProject', blk) == 0) then
697 writ%n_excited_states = parse_block_n(blk)
698 safe_allocate(writ%excited_st(1:writ%n_excited_states))
699 do ist = 1, writ%n_excited_states
700 call parse_block_string(blk, ist-1, 0, filename)
701 call excited_states_init(writ%excited_st(ist), writ%gs_st, trim(filename), namespace)
702 end do
703 else
704 writ%n_excited_states = 0
705 end if
706 end if
707
708 !%Variable TDOutputComputeInterval
709 !%Type integer
710 !%Default 50
711 !%Section Time-Dependent::TD Output
712 !%Description
713 !% The TD output requested are computed
714 !% when the iteration number is a multiple of the <tt>TDOutputComputeInterval</tt> variable.
715 !% Must be >= 0. If it is 0, then no output is written.
716 !% Implemented only for projections and number of excited electrons for the moment.
717 !%End
718 call parse_variable(namespace, 'TDOutputComputeInterval', 50, writ%compute_interval)
719 if (writ%compute_interval < 0) then
720 message(1) = "TDOutputComputeInterval must be >= 0."
721 call messages_fatal(1, namespace=namespace)
722 end if
723
724 ! ----------------------------------------------
725 ! Initialize write file handlers
726 ! ----------------------------------------------
727
728 ! Step
729 if (iter == 0) then
730 first = 0
731 else
732 first = iter + 1
733 end if
734
735 ! Root dir for TD files
736 call io_mkdir('td.general', namespace)
737
738 ! ----------------------------------------------
739 ! Initialize write that are MPI agnostic
740 ! ----------------------------------------------
741
742 ! Default
743 writ%out(:)%mpi_grp = mpi_world
744
745 if (mpi_grp_is_root(mpi_world)) then
746
747 do ifile = 1, out_max
748 ! Exceptions that are handled later
749 if (any([out_multipoles, out_laser, out_ftchd] == ifile)) cycle
750
751 if (writ%out(ifile)%write) then
752 call write_iter_init(writ%out(ifile)%handle, &
753 first, &
754 units_from_atomic(units_out%time, dt), &
755 trim(io_workpath("td.general/"//trim(td_file_name(ifile)), namespace)))
756 end if
757
758 enddo
759
760 ! Exceptions
761
762 ! Multipoles, when MPI is not state-parallel
763 if (writ%out(out_multipoles)%write .and. .not. resolve_states) then
764 call write_iter_init(writ%out(out_multipoles)%handle, &
765 first, units_from_atomic(units_out%time, dt), &
766 trim(io_workpath("td.general/multipoles", namespace)))
767 end if
768
769 if (writ%out(out_ftchd)%write) then
770 select case (kick%qkick_mode)
771 case (qkickmode_sin)
772 write(filename, '(a)') 'td.general/ftchd.sin'
773 case (qkickmode_cos)
774 write(filename, '(a)') 'td.general/ftchd.cos'
775 case (qkickmode_bessel)
776 write(filename, '(a, SP, I0.3, a, I0.3)') 'td.general/ftchd.l', kick%qbessel_l, '_m', kick%qbessel_m
777 case default
778 write(filename, '(a)') 'td.general/ftchd'
779 end select
780 call write_iter_init(writ%out(out_ftchd)%handle, &
781 first, units_from_atomic(units_out%time, dt), trim(io_workpath(filename, namespace)))
782 end if
783
784 if (writ%out(out_laser)%write) then
785 if(associated(list_get_lasers(ext_partners))) then
786 ! The laser file is written for the full propagation in one go, so that
787 ! the user can check that the laser is correct and as intended before letting
788 ! the code run for a possibly large period of time. This is done even after
789 ! a restart, so that it takes into account any changes to max_iter.
790 call io_rm("td.general/laser", namespace=namespace)
791 call write_iter_init(writ%out(out_laser)%handle, 0, &
792 units_from_atomic(units_out%time, dt), &
793 trim(io_workpath("td.general/laser", namespace)))
794 do ii = 0, max_iter
795 call td_write_laser(writ%out(out_laser)%handle, space, list_get_lasers(ext_partners), dt, ii)
796 end do
797 call write_iter_end(writ%out(out_laser)%handle)
798 end if
799 end if
800
801 end if ! mpi_grp_is_root(mpi_world)
802
803 ! ----------------------------------------------
804 ! Initialize write that are MPI group-specific
805 ! ----------------------------------------------
806
807 if (writ%out(out_multipoles)%write .and. resolve_states) then
808 !resolve state contribution on multipoles
809 writ%out(out_multipoles)%hand_start = st%st_start
810 writ%out(out_multipoles)%hand_end = st%st_end
811 writ%out(out_multipoles)%resolve_states = .true.
812 writ%out(out_multipoles)%mpi_grp = gr%mpi_grp
813
814 safe_allocate(writ%out(out_multipoles)%mult_handles(st%st_start:st%st_end))
815
816 if (mpi_grp_is_root(writ%out(out_multipoles)%mpi_grp)) then
817 do ist = st%st_start, st%st_end
818 write(filename, '(a,i4.4)') 'td.general/multipoles-ist', ist
819 call write_iter_init(writ%out(out_multipoles)%mult_handles(ist), &
820 first, units_from_atomic(units_out%time, dt), &
821 trim(io_workpath(filename, namespace)))
822 end do
823 end if
824 end if
825
826 ! Misc operations
827
828 if (writ%out(out_total_current)%write .or. writ%out(out_total_heat_current)%write) then
829 !TODO: we should only compute the current here, not v_ks
830 call v_ks_calculate_current(ks, .true.)
831 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
832 calc_eigenval=.false., time = iter*dt, calc_energy = .false.)
833 end if
834
835 if (writ%out(out_n_ex)%write .and. writ%compute_interval > 0) then
836 call io_mkdir(outp%iter_dir, namespace)
837 end if
838
839 if (all(outp%how == 0) .and. writ%out(out_n_ex)%write) then
840 call io_function_read_what_how_when(namespace, space, outp%what, outp%how, outp%output_interval)
841 end if
842
843 ! --------------------------------------------------------
844 ! All steps of the above routine, but specific to DFT+U
845 ! --------------------------------------------------------
846
847 !%Variable TDOutputDFTU
848 !%Type flag
849 !%Default none
850 !%Section Time-Dependent::TD Output
851 !%Description
852 !% Defines what should be output during the time-dependent
853 !% simulation, related to DFT+U.
854 !%
855 !% Note: the output files generated by this option are updated
856 !% every <tt>RestartWriteInterval</tt> steps.
857 !%Option effective_u 1
858 !% Writes the effective U for each orbital set as a function of time.
859 !%End
860 default = 0
861 if (hm%lda_u_level == dft_u_acbn0) default = default + 2**(out_dftu_effective_u - 1)
862 call parse_variable(namespace, 'TDOutputDFTU', default, flags)
863
864 if (.not. varinfo_valid_option('TDOutputDFTU', flags, is_flag = .true.)) then
865 call messages_input_error(namespace, 'TDOutputDFTU')
866 end if
867
868 do iout = 1, out_dftu_max
869 writ%out_dftu(iout)%write = (iand(flags, 2**(iout - 1)) /= 0)
870 end do
871
872 if (mpi_grp_is_root(mpi_world)) then
873 if (writ%out_dftu(out_dftu_effective_u)%write) then
874 call write_iter_init(writ%out_dftu(out_dftu_effective_u)%handle, &
875 first, units_from_atomic(units_out%time, dt), &
876 trim(io_workpath("td.general/effectiveU", namespace)))
877 end if
878 end if
879
880 ! Init matrix elements calculator
881 call writ%elec_me%init(gr, space, st)
882
883 pop_sub(td_write_init)
884 end subroutine td_write_init
885
886
887 ! ---------------------------------------------------------
888 subroutine td_write_end(writ)
889 type(td_write_t), intent(inout) :: writ
890
891 integer :: ist, iout
892
893 push_sub(td_write_end)
894
895 do iout = 1, out_max
896 if (iout == out_laser) cycle
897 if (writ%out(iout)%write) then
898 if (mpi_grp_is_root(writ%out(iout)%mpi_grp)) then
899 if (writ%out(iout)%resolve_states) then
900 do ist = writ%out(iout)%hand_start, writ%out(iout)%hand_end
901 call write_iter_end(writ%out(iout)%mult_handles(ist))
902 end do
903 safe_deallocate_a(writ%out(iout)%mult_handles)
904 else
905 call write_iter_end(writ%out(iout)%handle)
906 end if
907 end if
908 end if
909 end do
910
911 if (mpi_grp_is_root(mpi_world)) then
912 do iout = 1, out_dftu_max
913 if (writ%out_dftu(iout)%write) call write_iter_end(writ%out_dftu(iout)%handle)
914 end do
915
916 end if
917
918 if (writ%out(out_populations)%write) then
919 do ist = 1, writ%n_excited_states
920 call excited_states_kill(writ%excited_st(ist))
921 end do
922 writ%n_excited_states = 0
923 end if
924
925 if (writ%out(out_proj)%write .or. writ%out(out_populations)%write &
926 .or. writ%out(out_n_ex)%write .or. writ%out(out_kp_proj)%write) then
927 call states_elec_end(writ%gs_st)
928 end if
929
930 pop_sub(td_write_end)
931 end subroutine td_write_end
932
933
934 ! ---------------------------------------------------------
935 subroutine td_write_iter(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, kick, ks, dt, iter, mc, recalculate_gs)
936 type(td_write_t), intent(inout) :: writ
937 type(namespace_t), intent(in) :: namespace
938 class(space_t), intent(in) :: space
939 type(output_t), intent(in) :: outp
940 type(grid_t), intent(in) :: gr
941 type(states_elec_t), intent(inout) :: st
942 type(hamiltonian_elec_t), intent(inout) :: hm
943 type(ions_t), intent(inout) :: ions
944 type(partner_list_t), intent(in) :: ext_partners
945 type(kick_t), intent(in) :: kick
946 type(v_ks_t), intent(in) :: ks
947 real(real64), intent(in) :: dt
948 integer, intent(in) :: iter
949 type(multicomm_t), intent(in) :: mc
950 logical, intent(in) :: recalculate_gs
951
952 type(gauge_field_t), pointer :: gfield
953 integer :: ierr
954 type(restart_t) :: restart_gs
955
956 push_sub_with_profile(td_write_iter)
957
958 if (writ%out(out_multipoles)%write) then
959 call td_write_multipole(writ%out(out_multipoles), space, gr, ions, st, writ%lmax, kick, iter)
960 end if
961
962 if (writ%out(out_ftchd)%write) then
963 call td_write_ftchd(writ%out(out_ftchd)%handle, space, gr, st, kick, iter)
964 end if
965
966 if (writ%out(out_angular)%write) then
967 call td_write_angular(writ%out(out_angular)%handle, namespace, space, gr, ions, hm, st, kick, iter)
968 end if
969
970 if (writ%out(out_spin)%write) then
971 call td_write_spin(writ%out(out_spin)%handle, gr, st, iter)
972 end if
973
974 if (writ%out(out_magnets)%write) then
975 call td_write_local_magnetic_moments(writ%out(out_magnets)%handle, gr, st, ions, writ%lmm_r, iter)
976 end if
977
978 if (writ%out(out_tot_m)%write) then
979 call td_write_tot_mag(writ%out(out_tot_m)%handle, gr, st, kick, iter)
980 end if
982 if (writ%out(out_proj)%write .and. mod(iter, writ%compute_interval) == 0) then
983 if (mpi_grp_is_root(mpi_world)) call write_iter_set(writ%out(out_proj)%handle, iter)
984 call td_write_proj(writ%out(out_proj)%handle, space, gr, ions, st, writ%gs_st, kick, iter)
985 end if
986
987 if (writ%out(out_floquet)%write) then
988 call td_write_floquet(namespace, space, hm, ext_partners, gr, st, iter)
989 end if
990
991 if (writ%out(out_kp_proj)%write .and. mod(iter, writ%compute_interval) == 0) then
992 call td_write_proj_kp(gr, hm%kpoints, st, writ%gs_st, namespace, iter)
993 end if
994
995 if (writ%out(out_coords)%write) then
996 call td_write_coordinates(writ%out(out_coords)%handle, ions%natoms, ions%space, &
997 ions%pos, ions%vel, ions%tot_force, iter)
998 end if
999
1000 if (writ%out(out_separate_coords)%write) then
1001 call td_write_sep_coordinates(writ%out(out_separate_coords)%handle, ions%natoms, ions%space, &
1002 ions%pos, ions%vel, ions%tot_force, iter, 1)
1003 end if
1004
1005 if (writ%out(out_separate_velocity)%write) then
1006 call td_write_sep_coordinates(writ%out(out_separate_velocity)%handle, ions%natoms, ions%space, &
1007 ions%pos, ions%vel, ions%tot_force, iter, 2)
1008 end if
1009
1010 if (writ%out(out_separate_forces)%write) then
1011 call td_write_sep_coordinates(writ%out(out_separate_forces)%handle, ions%natoms, ions%space, &
1012 ions%pos, ions%vel, ions%tot_force, iter, 3)
1013 end if
1014
1015 if (writ%out(out_temperature)%write) then
1016 call td_write_temperature(writ%out(out_temperature)%handle, ions, iter)
1017 end if
1018
1019 if (writ%out(out_populations)%write) then
1020 call td_write_populations(writ%out(out_populations)%handle, namespace, space, gr, st, writ, dt, iter)
1021 end if
1022
1023 if (writ%out(out_acc)%write) then
1024 call td_write_acc(writ%out(out_acc)%handle, namespace, space, gr, ions, st, hm, ext_partners, dt, iter)
1025 end if
1026
1027 if (writ%out(out_vel)%write) then
1028 call td_write_vel(writ%out(out_vel)%handle, writ%elec_me, hm%kpoints, iter)
1029 end if
1030
1031 ! td_write_laser no longer called here, because the whole laser is printed
1032 ! out at the beginning.
1033
1034 if (writ%out(out_energy)%write) then
1035 call td_write_energy(writ%out(out_energy)%handle, hm, iter, ions%kinetic_energy)
1036 end if
1037
1038 if (writ%out(out_gauge_field)%write) then
1039 gfield => list_get_gauge_field(ext_partners)
1040 if(associated(gfield)) then
1041 call gauge_field_output_write(gfield, writ%out(out_gauge_field)%handle, iter)
1042 end if
1043 end if
1044
1045 if (writ%out(out_eigs)%write) then
1046 call td_write_eigs(writ%out(out_eigs)%handle, st, iter)
1047 end if
1048
1049 if (writ%out(out_ion_ch)%write) then
1050 call td_write_ionch(writ%out(out_ion_ch)%handle, gr, st, iter)
1051 end if
1052
1053 if (writ%out(out_total_current)%write) then
1054 call td_write_total_current(writ%out(out_total_current)%handle, space, gr, st, iter)
1055 end if
1056
1057 if (writ%out(out_total_heat_current)%write) then
1058 call td_write_total_heat_current(writ%out(out_total_heat_current)%handle, space, hm, gr, st, iter)
1059 end if
1060
1061 if (writ%out(out_partial_charges)%write) then
1062 call td_write_partial_charges(writ%out(out_partial_charges)%handle, gr, st, &
1063 ions, iter)
1064 end if
1065
1066 if (writ%out(out_n_ex)%write .and. mod(iter, writ%compute_interval) == 0) then
1067 if (mpi_grp_is_root(mpi_world)) call write_iter_set(writ%out(out_n_ex)%handle, iter)
1068 if (recalculate_gs) then ! Load recomputed GS states
1069 call restart_init(restart_gs, namespace, restart_proj, restart_type_load, mc, ierr, mesh=gr)
1070 call states_elec_load(restart_gs, namespace, space, writ%gs_st, gr, hm%kpoints, &
1071 ierr, label = ': Houston states for TDOutput')
1073 end if
1074
1075 call td_write_n_ex(writ%out(out_n_ex)%handle, outp, namespace, gr, hm%kpoints, st, writ%gs_st, iter)
1076 end if
1077
1078 if (writ%out(out_norm_ks)%write) then
1079 call td_write_norm_ks_orbitals(writ%out(out_norm_ks)%handle, gr, hm%kpoints, st, iter)
1080 end if
1081
1082 !DFT+U outputs
1083 if (writ%out_dftu(out_dftu_effective_u)%write) then
1084 call td_write_effective_u(writ%out_dftu(out_dftu_effective_u)%handle, hm%lda_u, iter)
1085 end if
1086
1087 if (writ%out(out_q)%write .and. ks%has_photons) then
1088 call td_write_q(writ%out(out_q)%handle, space, ks, iter)
1089 end if
1090
1091 if (writ%out(out_mxll_field)%write .and. hm%mxll%calc_field_dip) then
1092 call td_write_mxll_field(writ%out(out_mxll_field)%handle, space, hm, dt, iter)
1093 end if
1094
1095 pop_sub_with_profile(td_write_iter)
1096 end subroutine td_write_iter
1097
1098
1099 ! ---------------------------------------------------------
1100 subroutine td_write_data(writ)
1101 type(td_write_t), intent(inout) :: writ
1102
1103 integer :: iout, ii
1104
1105 push_sub(td_write_data)
1106 call profiling_in("TD_WRITE_DATA")
1107
1108 do iout = 1, out_max
1109 if (iout == out_laser) cycle
1110 if (writ%out(iout)%write) then
1111 if (mpi_grp_is_root(writ%out(iout)%mpi_grp)) then
1112 if (writ%out(iout)%resolve_states) then
1113 do ii = writ%out(iout)%hand_start, writ%out(iout)%hand_end
1114 call write_iter_flush(writ%out(iout)%mult_handles(ii))
1115 end do
1116 else
1117 call write_iter_flush(writ%out(iout)%handle)
1118 end if
1119 end if
1120 end if
1121 end do
1122
1123 if (mpi_grp_is_root(mpi_world)) then
1124 do iout = 1, out_dftu_max
1125 if (writ%out_dftu(iout)%write) call write_iter_flush(writ%out_dftu(iout)%handle)
1126 end do
1127 end if
1128
1129 call profiling_out("TD_WRITE_DATA")
1130 pop_sub(td_write_data)
1131 end subroutine td_write_data
1132
1133 ! ---------------------------------------------------------
1134 subroutine td_write_output(namespace, space, gr, st, hm, ks, outp, ions, ext_partners, iter, dt)
1135 type(namespace_t), intent(in) :: namespace
1136 type(electron_space_t), intent(in) :: space
1137 type(grid_t), intent(in) :: gr
1138 type(states_elec_t), intent(inout) :: st
1139 type(hamiltonian_elec_t), intent(inout) :: hm
1140 type(v_ks_t), intent(inout) :: ks
1141 type(output_t), intent(in) :: outp
1142 type(ions_t), intent(in) :: ions
1143 type(partner_list_t), intent(in) :: ext_partners
1144 integer, intent(in) :: iter
1145 real(real64), optional, intent(in) :: dt
1146
1147 character(len=256) :: filename
1148
1149 push_sub(td_write_output)
1150 call profiling_in("TD_WRITE_OUTPUT")
1151
1152 ! TODO this now overwrites wf inside st. If this is not wanted need to add an optional overwrite=no flag
1153 if (st%modelmbparticles%nparticle > 0) then
1154 call modelmb_sym_all_states(space, gr, st)
1155 end if
1156
1157 ! now write down the rest
1158 write(filename, '(a,a,i7.7)') trim(outp%iter_dir),"td.", iter ! name of directory
1159
1160 call output_all(outp, namespace, space, filename, gr, ions, iter, st, hm, ks)
1161
1162 call output_modelmb(outp, namespace, space, filename, gr, ions, iter, st)
1163
1164 if (present(dt)) then
1165 call output_scalar_pot(outp, namespace, space, filename, gr, ions, ext_partners, iter*dt)
1166 else
1167 if (iter == 0) call output_scalar_pot(outp, namespace, space, filename, gr, ions, ext_partners)
1168 end if
1169
1170 call profiling_out("TD_WRITE_OUTPUT")
1171 pop_sub(td_write_output)
1172 end subroutine td_write_output
1173
1174 ! ---------------------------------------------------------
1175 subroutine td_write_spin(out_spin, mesh, st, iter)
1176 type(c_ptr), intent(inout) :: out_spin
1177 class(mesh_t), intent(in) :: mesh
1178 type(states_elec_t), intent(in) :: st
1179 integer, intent(in) :: iter
1180
1181 character(len=130) :: aux
1182 real(real64) :: spin(3)
1183
1184 push_sub(td_write_spin)
1185
1186 ! The expectation value of the spin operator is half the total magnetic moment
1187 ! This has to be calculated by all nodes
1188 call magnetic_moment(mesh, st, st%rho, spin)
1189 spin = m_half*spin
1190
1191 if (mpi_grp_is_root(mpi_world)) then ! only first node outputs
1192
1193 if (iter == 0) then
1195
1196 !second line -> columns name
1198 if (st%d%ispin == spinors) then
1199 write(aux, '(a2,18x)') 'Sx'
1200 call write_iter_header(out_spin, aux)
1201 write(aux, '(a2,18x)') 'Sy'
1202 call write_iter_header(out_spin, aux)
1203 end if
1204 write(aux, '(a2,18x)') 'Sz'
1205 call write_iter_header(out_spin, aux)
1207
1209 end if
1210
1212 select case (st%d%ispin)
1213 case (spin_polarized)
1214 call write_iter_double(out_spin, spin(3), 1)
1215 case (spinors)
1216 call write_iter_double(out_spin, spin(1:3), 3)
1217 end select
1219
1220 end if
1221
1222 pop_sub(td_write_spin)
1223 end subroutine td_write_spin
1224
1225
1226 ! ---------------------------------------------------------
1227 subroutine td_write_local_magnetic_moments(out_magnets, gr, st, ions, lmm_r, iter)
1228 type(c_ptr), intent(inout) :: out_magnets
1229 type(grid_t), intent(in) :: gr
1230 type(states_elec_t), intent(in) :: st
1231 type(ions_t), intent(in) :: ions
1232 real(real64), intent(in) :: lmm_r
1233 integer, intent(in) :: iter
1234
1235 integer :: ia
1236 character(len=50) :: aux
1237 real(real64), allocatable :: lmm(:,:)
1238
1240
1241 !get the atoms` magnetization. This has to be calculated by all nodes
1242 safe_allocate(lmm(1:3, 1:ions%natoms))
1243 call magnetic_local_moments(gr, st, ions, gr%der%boundaries, st%rho, lmm_r, lmm)
1244
1245 if (mpi_grp_is_root(mpi_world)) then ! only first node outputs
1246
1247 if (iter == 0) then
1249
1250 !second line -> columns name
1252 do ia = 1, ions%natoms
1253 if (st%d%ispin == spinors) then
1254 write(aux, '(a2,i2.2,16x)') 'mx', ia
1256 write(aux, '(a2,i2.2,16x)') 'my', ia
1258 end if
1259 write(aux, '(a2,i2.2,16x)') 'mz', ia
1261 end do
1263
1265 end if
1266
1268 do ia = 1, ions%natoms
1269 select case (st%d%ispin)
1270 case (spin_polarized)
1271 call write_iter_double(out_magnets, lmm(3, ia), 1)
1272 case (spinors)
1273 call write_iter_double(out_magnets, lmm(1:3, ia), 3)
1274 end select
1275 end do
1277 safe_deallocate_a(lmm)
1278 end if
1279
1281 end subroutine td_write_local_magnetic_moments
1282
1283 ! ---------------------------------------------------------
1284 subroutine td_write_tot_mag(out_magnets, mesh, st, kick, iter)
1285 type(c_ptr), intent(inout) :: out_magnets
1286 class(mesh_t), intent(in) :: mesh
1287 type(states_elec_t), intent(in) :: st
1288 type(kick_t), intent(in) :: kick
1289 integer, intent(in) :: iter
1290
1291 complex(real64), allocatable :: tm(:,:)
1292 integer :: ii, iq
1293
1294 push_sub(td_write_tot_mag)
1295
1296 safe_allocate(tm(1:6,1:kick%nqvec))
1297
1298 do iq = 1, kick%nqvec
1299 call magnetic_total_magnetization(mesh, st, kick%qvector(:,iq), tm(1:6,iq))
1300 end do
1301
1302 if (mpi_grp_is_root(mpi_world)) then ! only first node outputs
1303
1304 if (iter == 0) then
1305 call td_write_print_header_init(out_magnets)
1306 call kick_write(kick, out = out_magnets)
1307
1308 !second line -> columns name
1309 call write_iter_header_start(out_magnets)
1310 call write_iter_header(out_magnets, 'Re[m_x(q)]')
1311 call write_iter_header(out_magnets, 'Im[m_x(q)]')
1312 call write_iter_header(out_magnets, 'Re[m_y(q)]')
1313 call write_iter_header(out_magnets, 'Im[m_y(q)]')
1314 call write_iter_header(out_magnets, 'Re[m_z(q)]')
1315 call write_iter_header(out_magnets, 'Im[m_z(q)]')
1316 call write_iter_header(out_magnets, 'Re[m_x(-q)]')
1317 call write_iter_header(out_magnets, 'Im[m_x(-q)]')
1318 call write_iter_header(out_magnets, 'Re[m_y(-q)]')
1319 call write_iter_header(out_magnets, 'Im[m_y(-q)]')
1320 call write_iter_header(out_magnets, 'Re[m_z(-q)]')
1321 call write_iter_header(out_magnets, 'Im[m_z(-q)]')
1322 call write_iter_nl(out_magnets)
1323
1324 call td_write_print_header_end(out_magnets)
1325 end if
1326
1327 call write_iter_start(out_magnets)
1328 do iq = 1, kick%nqvec
1329 do ii = 1, 6
1330 call write_iter_double(out_magnets, real(tm(ii, iq), real64), 1)
1331 call write_iter_double(out_magnets, aimag(tm(ii, iq)), 1)
1332 end do
1333 end do
1334 call write_iter_nl(out_magnets)
1335 end if
1336
1337 safe_deallocate_a(tm)
1338
1339 pop_sub(td_write_tot_mag)
1340 end subroutine td_write_tot_mag
1341
1342
1343 ! ---------------------------------------------------------
1351 subroutine td_write_angular(out_angular, namespace, space, gr, ions, hm, st, kick, iter)
1352 type(c_ptr), intent(inout) :: out_angular
1353 type(namespace_t), intent(in) :: namespace
1354 class(space_t), intent(in) :: space
1355 type(grid_t), intent(in) :: gr
1356 type(ions_t), intent(inout) :: ions
1357 type(hamiltonian_elec_t), intent(inout) :: hm
1358 type(states_elec_t), intent(inout) :: st
1359 type(kick_t), intent(in) :: kick
1360 integer, intent(in) :: iter
1361
1362 integer :: idir
1363 character(len=130) :: aux
1364 real(real64) :: angular(3)
1365 class(perturbation_magnetic_t), pointer :: angular_momentum
1366
1367 push_sub(td_write_angular)
1368
1369 angular_momentum => perturbation_magnetic_t(namespace, ions)
1370 do idir = 1, 3
1371 call angular_momentum%setup_dir(idir)
1372 !we have to multiply by 2, because the perturbation returns L/2
1373 angular(idir) = &
1374 m_two*real(angular_momentum%zstates_elec_expectation_value(namespace, space, gr, hm, st), real64)
1375 end do
1376 safe_deallocate_p(angular_momentum)
1378 if (mpi_grp_is_root(mpi_world)) then ! Only first node outputs
1379
1380 if (iter == 0) then
1381 call td_write_print_header_init(out_angular)
1382
1383 write(aux, '(a15,i2)') '# nspin ', st%d%nspin
1384 call write_iter_string(out_angular, aux)
1385 call write_iter_nl(out_angular)
1386
1387 call kick_write(kick, out = out_angular)
1388
1389 !second line -> columns name
1390 call write_iter_header_start(out_angular)
1391 write(aux, '(a4,18x)') '<Lx>'
1392 call write_iter_header(out_angular, aux)
1393 write(aux, '(a4,18x)') '<Ly>'
1394 call write_iter_header(out_angular, aux)
1395 write(aux, '(a4,18x)') '<Lz>'
1396 call write_iter_header(out_angular, aux)
1397 call write_iter_nl(out_angular)
1398
1399 !third line -> should hold the units.
1400 call write_iter_string(out_angular, '#[Iter n.]')
1401 call write_iter_header(out_angular, '[' // trim(units_abbrev(units_out%time)) // ']')
1402 call write_iter_header(out_angular, '[hbar]')
1403 call write_iter_header(out_angular, '[hbar]')
1404 call write_iter_header(out_angular, '[hbar]')
1405 call write_iter_nl(out_angular)
1406
1407 call td_write_print_header_end(out_angular)
1408 end if
1409
1410 call write_iter_start(out_angular)
1411 call write_iter_double(out_angular, angular(1:3), 3)
1412 call write_iter_nl(out_angular)
1413
1414 end if
1415
1416 pop_sub(td_write_angular)
1417 end subroutine td_write_angular
1418
1419
1422 subroutine td_write_multipole(out_multip, space, gr, ions, st, lmax, kick, iter)
1423 type(td_write_prop_t), intent(inout) :: out_multip
1424 class(space_t), intent(in) :: space
1425 type(grid_t), intent(in) :: gr
1426 type(ions_t), intent(in) :: ions
1427 type(states_elec_t), intent(in) :: st
1428 integer, intent(in) :: lmax
1429 type(kick_t), intent(in) :: kick
1430 integer, intent(in) :: iter
1431
1432 integer :: ist
1433 real(real64), allocatable :: rho(:,:)
1434
1435 push_sub(td_write_multipole)
1436
1437 if (out_multip%resolve_states) then
1438 safe_allocate(rho(1:gr%np_part, 1:st%d%nspin))
1439 rho(:,:) = m_zero
1440
1441 do ist = st%st_start, st%st_end
1442 call density_calc(st, gr, rho, istin = ist)
1443 call td_write_multipole_r(out_multip%mult_handles(ist), space, gr, ions, st, lmax, kick, rho, iter, &
1444 mpi_grp = out_multip%mpi_grp)
1445 end do
1446
1447 safe_deallocate_a(rho)
1448
1449 else
1450 if (allocated(st%frozen_rho)) then
1451 safe_allocate(rho(1:gr%np, 1:st%d%nspin))
1452 call lalg_copy(gr%np, st%d%nspin, st%rho, rho)
1453 call lalg_axpy(gr%np, st%d%nspin, m_one, st%frozen_rho, rho)
1454
1455 call td_write_multipole_r(out_multip%handle, space, gr, ions, st, lmax, kick, rho, iter)
1456
1457 safe_deallocate_a(rho)
1458 else
1459 call td_write_multipole_r(out_multip%handle, space, gr, ions, st, lmax, kick, st%rho, iter)
1460 end if
1461
1462 end if
1463
1464 pop_sub(td_write_multipole)
1465 end subroutine td_write_multipole
1466
1467
1469 subroutine td_write_multipole_r(out_multip, space, mesh, ions, st, lmax, kick, rho, iter, mpi_grp)
1470 type(c_ptr), intent(inout) :: out_multip
1471 class(space_t), intent(in) :: space
1472 class(mesh_t), intent(in) :: mesh
1473 type(ions_t), intent(in) :: ions
1474 type(states_elec_t), intent(in) :: st
1475 integer, intent(in) :: lmax
1476 type(kick_t), intent(in) :: kick
1477 real(real64), intent(in) :: rho(:,:)
1478 integer, intent(in) :: iter
1479 type(mpi_grp_t), optional, intent(in) :: mpi_grp
1480
1481
1482 integer :: is, idir, ll, mm, add_lm
1483 character(len=120) :: aux
1484 real(real64) :: ionic_dipole(ions%space%dim)
1485 real(real64), allocatable :: multipole(:,:)
1486 type(mpi_grp_t) :: mpi_grp_
1487
1488 push_sub(td_write_multipole_r)
1489
1490 ! We cannot output multipoles beyond the dipole for higher dimensions
1491 assert(.not. (lmax > 1 .and. space%dim > 3))
1492
1493 mpi_grp_ = mpi_world
1494 if (present(mpi_grp)) mpi_grp_ = mpi_grp
1495
1496 if (mpi_grp_is_root(mpi_grp_).and.iter == 0) then
1497 call td_write_print_header_init(out_multip)
1498
1499 write(aux, '(a15,i2)') '# nspin ', st%d%nspin
1500 call write_iter_string(out_multip, aux)
1501 call write_iter_nl(out_multip)
1502
1503 write(aux, '(a15,i2)') '# lmax ', lmax
1504 call write_iter_string(out_multip, aux)
1505 call write_iter_nl(out_multip)
1506
1507 call kick_write(kick, out = out_multip)
1508
1509 call write_iter_header_start(out_multip)
1510
1511 do is = 1, st%d%nspin
1512 write(aux,'(a18,i1,a1)') 'Electronic charge(', is,')'
1513 call write_iter_header(out_multip, aux)
1514 if (lmax > 0) then
1515 do idir = 1, space%dim
1516 write(aux, '(4a1,i1,a1)') '<', index2axis(idir), '>', '(', is,')'
1517 call write_iter_header(out_multip, aux)
1518 end do
1519 end if
1520 do ll = 2, lmax
1521 do mm = -ll, ll
1522 write(aux, '(a2,i2,a4,i2,a2,i1,a1)') 'l=', ll, ', m=', mm, ' (', is,')'
1523 call write_iter_header(out_multip, aux)
1524 end do
1525 end do
1526 end do
1527 call write_iter_nl(out_multip)
1528
1529 ! units
1530 call write_iter_string(out_multip, '#[Iter n.]')
1531 call write_iter_header(out_multip, '[' // trim(units_abbrev(units_out%time)) // ']')
1532
1533 do is = 1, st%d%nspin
1534 call write_iter_header(out_multip, 'Electrons')
1535 if (lmax > 0) then
1536 do idir = 1, space%dim
1537 call write_iter_header(out_multip, '[' // trim(units_abbrev(units_out%length)) // ']')
1538 end do
1539 end if
1540 do ll = 2, lmax
1541 do mm = -ll, ll
1542 write(aux, '(a,a2,i1)') trim(units_abbrev(units_out%length)), "**", ll
1543 call write_iter_header(out_multip, '[' // trim(aux) // ']')
1544 end do
1545 end do
1546 end do
1547 call write_iter_nl(out_multip)
1548
1549 call td_write_print_header_end(out_multip)
1550 end if
1551
1552 if (space%dim > 3 .and. lmax == 1) then
1553 ! For higher dimensions we can only have up to the dipole
1554 safe_allocate(multipole(1:space%dim+1, 1:st%d%nspin))
1555 else
1556 safe_allocate(multipole(1:(lmax + 1)**2, 1:st%d%nspin))
1557 end if
1558 multipole(:,:) = m_zero
1559
1560 do is = 1, st%d%nspin
1561 call dmf_multipoles(mesh, rho(:,is), lmax, multipole(:,is))
1562 end do
1563
1564 if (lmax > 0) then
1565 ionic_dipole = ions%dipole()
1566 do is = 1, st%d%nspin
1567 multipole(2:space%dim+1, is) = -ionic_dipole(1:space%dim)/st%d%nspin - multipole(2:space%dim+1, is)
1568 end do
1569 end if
1570
1571 if (mpi_grp_is_root(mpi_grp_)) then
1572 call write_iter_start(out_multip)
1573 do is = 1, st%d%nspin
1574 call write_iter_double(out_multip, units_from_atomic(units_out%length**0, multipole(1, is)), 1)
1575 if (lmax > 0) then
1576 do idir = 1, space%dim
1577 call write_iter_double(out_multip, units_from_atomic(units_out%length, multipole(1+idir, is)), 1)
1578 end do
1579 end if
1580 add_lm = space%dim + 2
1581 do ll = 2, lmax
1582 do mm = -ll, ll
1583 call write_iter_double(out_multip, units_from_atomic(units_out%length**ll, multipole(add_lm, is)), 1)
1584 add_lm = add_lm + 1
1585 end do
1586 end do
1587 end do
1588 call write_iter_nl(out_multip)
1589 end if
1590
1591 safe_deallocate_a(multipole)
1592 pop_sub(td_write_multipole_r)
1593 end subroutine td_write_multipole_r
1594
1595 ! ---------------------------------------------------------
1596 subroutine td_write_ftchd(out_ftchd, space, mesh, st, kick, iter)
1597 type(c_ptr), intent(inout) :: out_ftchd
1598 class(space_t), intent(in) :: space
1599 class(mesh_t), intent(in) :: mesh
1600 type(states_elec_t), intent(in) :: st
1601 type(kick_t), intent(in) :: kick
1602 integer, intent(in) :: iter
1603
1604 integer :: is, ip, idir
1605 character(len=120) :: aux, aux2
1606 real(real64) :: ftchd_bessel
1607 complex(real64) :: ftchd
1608 real(real64) :: ylm
1609 real(real64), allocatable :: integrand_bessel(:)
1610 complex(real64), allocatable :: integrand(:)
1611
1612 push_sub(td_write_ftchd)
1613
1614 if (mpi_grp_is_root(mpi_world).and.iter == 0) then
1615 call td_write_print_header_init(out_ftchd)
1616
1617 write(aux,'(a15, i2)') '# qkickmode ', kick%qkick_mode
1618 call write_iter_string(out_ftchd, aux)
1619 call write_iter_nl(out_ftchd)
1620
1621 if (kick%qkick_mode == qkickmode_bessel) then
1622 write(aux,'(a15, i0.3, 1x, i0.3)') '# ll, mm ', kick%qbessel_l, kick%qbessel_m
1623 call write_iter_string(out_ftchd, aux)
1624 call write_iter_nl(out_ftchd)
1625 end if
1626
1627 if (kick%qkick_mode == qkickmode_bessel) then
1628 write(aux, '(a15, f9.6)') '# qlength ', kick%qlength
1629 else ! sin or cos
1630 write(aux, '(a15)') '# qvector '
1631 do idir = 1, space%dim
1632 write(aux2, '(f9.5)') kick%qvector(idir,1)
1633 aux = trim(aux) // trim(aux2)
1634 end do
1635 end if
1636 call write_iter_string(out_ftchd, aux)
1637 call write_iter_nl(out_ftchd)
1638
1639 write(aux, '(a15,f18.12)') '# kick strength', kick%delta_strength
1640 call write_iter_string(out_ftchd, aux)
1641 call write_iter_nl(out_ftchd)
1642
1643 call write_iter_header_start(out_ftchd)
1644 if (kick%qkick_mode == qkickmode_bessel) then
1645 write(aux,'(a17)') 'int(j_l*Y_lm*rho)'
1646 else
1647 write(aux,'(a12)') 'Real, Imag'
1648 end if
1649 call write_iter_header(out_ftchd, aux)
1650 call write_iter_nl(out_ftchd)
1651
1652 ! units
1653 call write_iter_string(out_ftchd, '#[Iter n.]')
1654 call write_iter_header(out_ftchd, '[' // trim(units_abbrev(units_out%time)) // ']')
1655 call write_iter_nl(out_ftchd)
1656 call td_write_print_header_end(out_ftchd)
1657
1658 end if
1659
1660 ftchd = m_zero
1661
1662 ! If kick mode is exp, sin, or cos, apply the normal Fourier transform
1663 if (kick%qkick_mode /= qkickmode_bessel) then
1664 safe_allocate(integrand(1:mesh%np))
1665 integrand = m_zero
1666 do is = 1, st%d%nspin
1667 do ip = 1, mesh%np
1668 integrand(ip) = integrand(ip) + st%rho(ip, is) * exp(-m_zi*sum(mesh%x(ip, 1:space%dim)*kick%qvector(1:space%dim, 1)))
1669 end do
1670 end do
1671 ftchd = zmf_integrate(mesh, integrand)
1672 safe_deallocate_a(integrand)
1673 else
1674 ftchd_bessel = m_zero
1675 safe_allocate(integrand_bessel(1:mesh%np))
1676 integrand_bessel = m_zero
1677 do is = 1, st%d%nspin
1678 do ip = 1, mesh%np
1679 call ylmr_real(mesh%x(ip, 1:3), kick%qbessel_l, kick%qbessel_m, ylm)
1680 integrand_bessel(ip) = integrand_bessel(ip) + st%rho(ip, is) * &
1681 loct_sph_bessel(kick%qbessel_l, kick%qlength*norm2(mesh%x(ip, :)))*ylm
1682 end do
1683 end do
1684 ftchd_bessel = dmf_integrate(mesh, integrand_bessel)
1685 safe_deallocate_a(integrand_bessel)
1686 end if
1687
1688 if (mpi_grp_is_root(mpi_world)) then
1689 call write_iter_start(out_ftchd)
1690 if (kick%qkick_mode == qkickmode_bessel) then
1691 call write_iter_double(out_ftchd, ftchd_bessel, 1)
1692 else ! exp, sin, cos
1693 call write_iter_double(out_ftchd, real(ftchd), 1)
1694 call write_iter_double(out_ftchd, aimag(ftchd), 1)
1695 end if
1696 call write_iter_nl(out_ftchd)
1697 end if
1698
1699 pop_sub(td_write_ftchd)
1700 end subroutine td_write_ftchd
1701
1702 ! ---------------------------------------------------------
1703 subroutine td_write_temperature(out_temperature, ions, iter)
1704 type(c_ptr), intent(inout) :: out_temperature
1705 type(ions_t), intent(in) :: ions
1706 integer, intent(in) :: iter
1707
1708 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
1709
1710 push_sub(td_write_temperature)
1711
1712 if (iter == 0) then
1713 call td_write_print_header_init(out_temperature)
1714
1715 ! first line: column names
1716 call write_iter_header_start(out_temperature)
1717 call write_iter_header(out_temperature, 'Temperature')
1718 call write_iter_nl(out_temperature)
1719
1720 ! second line: units
1721 call write_iter_string(out_temperature, '#[Iter n.]')
1722 call write_iter_header(out_temperature, '[' // trim(units_abbrev(units_out%time)) // ']')
1723 call write_iter_string(out_temperature, ' [K]')
1724 call write_iter_nl(out_temperature)
1725
1726 call td_write_print_header_end(out_temperature)
1727 end if
1728
1729 call write_iter_start(out_temperature)
1730
1732
1733 call write_iter_nl(out_temperature)
1734
1735 pop_sub(td_write_temperature)
1736 end subroutine td_write_temperature
1737
1738
1739 ! ---------------------------------------------------------
1740 subroutine td_write_populations(out_populations, namespace, space, mesh, st, writ, dt, iter)
1741 type(c_ptr), intent(inout) :: out_populations
1742 type(namespace_t), intent(in) :: namespace
1743 class(space_t), intent(in) :: space
1744 class(mesh_t), intent(in) :: mesh
1745 type(states_elec_t), intent(inout) :: st
1746 type(td_write_t), intent(in) :: writ
1747 real(real64), intent(in) :: dt
1748 integer, intent(in) :: iter
1749
1750 integer :: ist
1751 character(len=6) :: excited_name
1752 complex(real64) :: gsp
1753 complex(real64), allocatable :: excited_state_p(:)
1754 complex(real64), allocatable :: dotprodmatrix(:, :, :)
1755
1756
1757 push_sub(td_write_populations)
1758
1759 safe_allocate(dotprodmatrix(1:writ%gs_st%nst, 1:st%nst, 1:st%nik))
1760 call zstates_elec_matrix(writ%gs_st, st, mesh, dotprodmatrix)
1761
1762
1763 !See comment in zstates_elec_mpdotp
1764 assert(.not. space%is_periodic())
1765
1766 ! all processors calculate the projection
1767 gsp = zstates_elec_mpdotp(namespace, mesh, writ%gs_st, st, dotprodmatrix)
1768
1769 if (writ%n_excited_states > 0) then
1770 safe_allocate(excited_state_p(1:writ%n_excited_states))
1771 do ist = 1, writ%n_excited_states
1772 excited_state_p(ist) = zstates_elec_mpdotp(namespace, mesh, writ%excited_st(ist), st, dotprodmatrix)
1773 end do
1774 end if
1775
1776 if (mpi_grp_is_root(mpi_world)) then
1777 if (iter == 0) then
1778 call td_write_print_header_init(out_populations)
1779
1780 ! first line -> column names
1781 call write_iter_header_start(out_populations)
1782 call write_iter_header(out_populations, 'Re<Phi_gs|Phi(t)>')
1783 call write_iter_header(out_populations, 'Im<Phi_gs|Phi(t)>')
1784 do ist = 1, writ%n_excited_states
1785 write(excited_name,'(a2,i3,a1)') 'P(', ist,')'
1786 call write_iter_header(out_populations, 'Re<'//excited_name//'|Phi(t)>')
1787 call write_iter_header(out_populations, 'Im<'//excited_name//'|Phi(t)>')
1788 end do
1789 call write_iter_nl(out_populations)
1790
1791 ! second line -> units
1792 call write_iter_string(out_populations, '#[Iter n.]')
1793 call write_iter_header(out_populations, '[' // trim(units_abbrev(units_out%time)) // ']')
1794 call write_iter_nl(out_populations)
1795
1796 call td_write_print_header_end(out_populations)
1797 end if
1798
1799 ! cannot call write_iter_start, for the step is not 1
1800 call write_iter_int(out_populations, iter, 1)
1801 call write_iter_double(out_populations, units_from_atomic(units_out%time, iter*dt), 1)
1802 call write_iter_double(out_populations, real(gsp), 1)
1803 call write_iter_double(out_populations, aimag(gsp), 1)
1804 do ist = 1, writ%n_excited_states
1805 call write_iter_double(out_populations, real(excited_state_p(ist)), 1)
1806 call write_iter_double(out_populations, aimag(excited_state_p(ist)), 1)
1807 end do
1808 call write_iter_nl(out_populations)
1809 end if
1810
1811 if (writ%n_excited_states > 0) then
1812 safe_deallocate_a(excited_state_p)
1813 end if
1814 safe_deallocate_a(dotprodmatrix)
1815 pop_sub(td_write_populations)
1816 end subroutine td_write_populations
1817
1818
1819 ! ---------------------------------------------------------
1820 subroutine td_write_acc(out_acc, namespace, space, gr, ions, st, hm, ext_partners, dt, iter)
1821 type(c_ptr), intent(inout) :: out_acc
1822 type(namespace_t), intent(in) :: namespace
1823 class(space_t), intent(in) :: space
1824 type(grid_t), intent(in) :: gr
1825 type(ions_t), intent(inout) :: ions
1826 type(states_elec_t), intent(inout) :: st
1827 type(hamiltonian_elec_t), intent(inout) :: hm
1828 type(partner_list_t), intent(in) :: ext_partners
1829 real(real64), intent(in) :: dt
1830 integer, intent(in) :: iter
1831
1832 integer :: idim
1833 character(len=7) :: aux
1834 real(real64) :: acc(space%dim)
1835
1836 push_sub(td_write_acc)
1837
1838 if (iter == 0 .and. mpi_grp_is_root(mpi_world)) then
1839 call td_write_print_header_init(out_acc)
1840
1841 ! first line -> column names
1842 call write_iter_header_start(out_acc)
1843 do idim = 1, space%dim
1844 write(aux, '(a4,i1,a1)') 'Acc(', idim, ')'
1845 call write_iter_header(out_acc, aux)
1846 end do
1847 call write_iter_nl(out_acc)
1848
1849 ! second line: units
1850 call write_iter_string(out_acc, '#[Iter n.]')
1851 call write_iter_header(out_acc, '[' // trim(units_abbrev(units_out%time)) // ']')
1852 do idim = 1, space%dim
1853 call write_iter_header(out_acc, '[' // trim(units_abbrev(units_out%acceleration)) // ']')
1854 end do
1855 call write_iter_nl(out_acc)
1856 call td_write_print_header_end(out_acc)
1857 end if
1858
1859 call td_calc_tacc(namespace, space, gr, ions, ext_partners, st, hm, acc, dt*iter)
1860
1861 if (mpi_grp_is_root(mpi_world)) then
1862 call write_iter_start(out_acc)
1863 acc = units_from_atomic(units_out%acceleration, acc)
1864 call write_iter_double(out_acc, acc, space%dim)
1865 call write_iter_nl(out_acc)
1866 end if
1867
1868 pop_sub(td_write_acc)
1869 end subroutine td_write_acc
1870
1871 ! ---------------------------------------------------------
1872 subroutine td_write_vel(out_vel, elec_me, kpoints, iter)
1873 type(c_ptr), intent(inout) :: out_vel
1874 type(elec_matrix_elements_t), intent(in) :: elec_me
1875 type(kpoints_t), intent(in) :: kpoints
1876 integer, intent(in) :: iter
1877
1878 integer :: idim
1879 character(len=7) :: aux
1880 real(real64) :: vel(elec_me%space%dim)
1881
1882 push_sub(td_write_vel)
1883
1884 if (iter == 0 .and. mpi_grp_is_root(mpi_world)) then
1885 call td_write_print_header_init(out_vel)
1886
1887 ! first line -> column names
1888 call write_iter_header_start(out_vel)
1889 do idim = 1, elec_me%space%dim
1890 write(aux, '(a4,i1,a1)') 'Vel(', idim, ')'
1891 call write_iter_header(out_vel, aux)
1892 end do
1893 call write_iter_nl(out_vel)
1894
1895 ! second line: units
1896 call write_iter_string(out_vel, '#[Iter n.]')
1897 call write_iter_header(out_vel, '[' // trim(units_abbrev(units_out%time)) // ']')
1898 do idim = 1, elec_me%space%dim
1899 call write_iter_header(out_vel, '[' // trim(units_abbrev(units_out%velocity)) // ']')
1900 end do
1901 call write_iter_nl(out_vel)
1902 call td_write_print_header_end(out_vel)
1903 end if
1904
1905 call td_calc_tvel(elec_me, kpoints, vel)
1906
1907 if (mpi_grp_is_root(mpi_world)) then
1908 call write_iter_start(out_vel)
1909 vel = units_from_atomic(units_out%velocity, vel)
1910 call write_iter_double(out_vel, vel, elec_me%space%dim)
1911 call write_iter_nl(out_vel)
1912 end if
1914 pop_sub(td_write_vel)
1915 end subroutine td_write_vel
1916
1917
1918 ! ---------------------------------------------------------
1919 subroutine td_write_laser(out_laser, space, lasers, dt, iter)
1920 type(c_ptr), intent(inout) :: out_laser
1921 class(space_t), intent(in) :: space
1922 type(lasers_t), intent(inout) :: lasers
1923 real(real64), intent(in) :: dt
1924 integer, intent(in) :: iter
1925
1926 integer :: il, idir
1927 real(real64) :: field(space%dim)
1928 real(real64) :: ndfield(space%dim)
1929 character(len=80) :: aux
1930
1931 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
1932
1933 ! no PUSH SUB, called too often
1934
1935 if (iter == 0) then
1936 call td_write_print_header_init(out_laser)
1937
1938 ! first line
1939 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, dt), &
1940 " [", trim(units_abbrev(units_out%time)), "]"
1941 call write_iter_string(out_laser, aux)
1942 call write_iter_nl(out_laser)
1943
1944 call write_iter_header_start(out_laser)
1945 do il = 1, lasers%no_lasers
1946 select case (laser_kind(lasers%lasers(il)))
1947 case (e_field_electric)
1948 do idir = 1, space%dim
1949 write(aux, '(a,i1,a)') 'E(', idir, ')'
1950 call write_iter_header(out_laser, aux)
1951 end do
1952 case (e_field_magnetic)
1953 do idir = 1, space%dim
1954 write(aux, '(a,i1,a)') 'B(', idir, ')'
1955 call write_iter_header(out_laser, aux)
1956 end do
1958 do idir = 1, space%dim
1959 write(aux, '(a,i1,a)') 'A(', idir, ')'
1960 call write_iter_header(out_laser, aux)
1961 end do
1963 write(aux, '(a,i1,a)') 'e(t)'
1964 call write_iter_header(out_laser, aux)
1965 end select
1966 end do
1967
1968 if (lasers_with_nondipole_field(lasers)) then
1969 do idir = 1, space%dim
1970 write(aux, '(a,i1,a)') 'A^M(', idir, ')'
1971 call write_iter_header(out_laser, aux)
1972 end do
1973 end if
1974 call write_iter_nl(out_laser)
1975
1976 call write_iter_string(out_laser, '#[Iter n.]')
1977 call write_iter_header(out_laser, '[' // trim(units_abbrev(units_out%time)) // ']')
1978
1979 ! Note that we do not print out units of E, B, or A, but rather units of e*E, e*B, e*A.
1980 ! (force, force, and energy, respectively). The reason is that the units of E, B or A
1981 ! are ugly.
1982 do il = 1, lasers%no_lasers
1983 select case (laser_kind(lasers%lasers(il)))
1985 aux = '[' // trim(units_abbrev(units_out%force)) // ']'
1986 do idir = 1, space%dim
1987 call write_iter_header(out_laser, aux)
1988 end do
1990 aux = '[' // trim(units_abbrev(units_out%energy)) // ']'
1991 do idir = 1, space%dim
1992 call write_iter_header(out_laser, aux)
1993 end do
1995 aux = '[adim]'
1996 call write_iter_header(out_laser, aux)
1997 end select
1998 end do
1999
2000 if (lasers_with_nondipole_field(lasers)) then
2001 aux = '[' // trim(units_abbrev(units_out%energy)) // ']'
2002 do idir = 1, space%dim
2003 call write_iter_header(out_laser, aux)
2004 end do
2005 end if
2006
2007
2008 call write_iter_nl(out_laser)
2009
2010 call td_write_print_header_end(out_laser)
2011 end if
2013 call write_iter_start(out_laser)
2014
2015 do il = 1, lasers%no_lasers
2016 field = m_zero
2017 call laser_field(lasers%lasers(il), field(1:space%dim), iter*dt)
2018 select case (laser_kind(lasers%lasers(il)))
2020 field = units_from_atomic(units_out%force, field)
2021 call write_iter_double(out_laser, field, space%dim)
2023 field = units_from_atomic(units_out%energy, field)
2024 call write_iter_double(out_laser, field, space%dim)
2026 call write_iter_double(out_laser, field(1), 1)
2027 end select
2028 end do
2029
2030 if (lasers_with_nondipole_field(lasers)) then
2031 call lasers_nondipole_laser_field_step(lasers, ndfield, iter*dt)
2032 call lasers_set_nondipole_parameters(lasers, ndfield, iter*dt)
2033 call write_iter_double(out_laser, ndfield, space%dim)
2034 end if
2035 call write_iter_nl(out_laser)
2036
2037 end subroutine td_write_laser
2038
2039
2040 ! ---------------------------------------------------------
2041 subroutine td_write_energy(out_energy, hm, iter, ke)
2042 type(c_ptr), intent(inout) :: out_energy
2043 type(hamiltonian_elec_t), intent(in) :: hm
2044 integer, intent(in) :: iter
2045 real(real64), intent(in) :: ke
2046
2047 integer :: ii
2048
2049 integer :: n_columns
2050
2051 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
2052
2053 push_sub(td_write_energy)
2054
2055 n_columns = 9
2056
2057 if (iter == 0) then
2058 call td_write_print_header_init(out_energy)
2059
2060 ! first line -> column names
2061 call write_iter_header_start(out_energy)
2062 call write_iter_header(out_energy, 'Total')
2063 call write_iter_header(out_energy, 'Kinetic (ions)')
2064 call write_iter_header(out_energy, 'Ion-Ion')
2065 call write_iter_header(out_energy, 'Electronic')
2066 call write_iter_header(out_energy, 'Eigenvalues')
2067 call write_iter_header(out_energy, 'Hartree')
2068 call write_iter_header(out_energy, 'Int[n v_xc]')
2069 call write_iter_header(out_energy, 'Exchange')
2070 call write_iter_header(out_energy, 'Correlation')
2071
2072 if (hm%pcm%run_pcm) then
2073 call write_iter_header(out_energy, 'E_M-solvent')
2074 n_columns = n_columns + 1
2075 end if
2076
2077 if (hm%lda_u_level /= dft_u_none) then
2078 call write_iter_header(out_energy, 'Hubbard')
2079 n_columns = n_columns + 1
2080 end if
2081
2082 call write_iter_nl(out_energy)
2083
2084 ! units
2085
2086 call write_iter_string(out_energy, '#[Iter n.]')
2087 call write_iter_header(out_energy, '[' // trim(units_abbrev(units_out%time)) // ']')
2088
2089 do ii = 1, n_columns
2090 call write_iter_header(out_energy, '[' // trim(units_abbrev(units_out%energy)) // ']')
2091 end do
2092 call write_iter_nl(out_energy)
2093
2094
2095 call td_write_print_header_end(out_energy)
2096 end if
2097
2098 call write_iter_start(out_energy)
2099 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%total+ke), 1)
2100 call write_iter_double(out_energy, units_from_atomic(units_out%energy, ke), 1)
2101 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%ep%eii), 1)
2102 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%total-hm%ep%eii), 1)
2103 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%eigenvalues), 1)
2104 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%hartree), 1)
2105 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%intnvxc), 1)
2106 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%exchange), 1)
2107 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%correlation), 1)
2108
2109 !adding the molecule-solvent electrostatic interaction
2110 if (hm%pcm%run_pcm) call write_iter_double(out_energy, &
2111 units_from_atomic(units_out%energy, hm%energy%int_ee_pcm + hm%energy%int_en_pcm + &
2112 hm%energy%int_nn_pcm + hm%energy%int_ne_pcm), 1)
2113
2114 if (hm%lda_u_level /= dft_u_none) then
2115 call write_iter_double(out_energy, units_from_atomic(units_out%energy, hm%energy%dft_u), 1)
2116 end if
2117
2118 call write_iter_nl(out_energy)
2119
2120 pop_sub(td_write_energy)
2121 end subroutine td_write_energy
2122
2123 ! ---------------------------------------------------------
2124 subroutine td_write_eigs(out_eigs, st, iter)
2125 type(c_ptr), intent(inout) :: out_eigs
2126 type(states_elec_t), intent(in) :: st
2127 integer, intent(in) :: iter
2128
2129 integer :: ii, is
2130 character(len=68) :: buf
2131
2132 push_sub(td_write_eigs)
2133
2135 pop_sub(td_write_eigs)
2136 return ! only first node outputs
2137 end if
2138
2139
2140 if (iter == 0) then
2141 call td_write_print_header_init(out_eigs)
2142
2143 write(buf, '(a15,i2)') '# nst ', st%nst
2144 call write_iter_string(out_eigs, buf)
2145 call write_iter_nl(out_eigs)
2146
2147 write(buf, '(a15,i2)') '# nspin ', st%d%nspin
2148 call write_iter_string(out_eigs, buf)
2149 call write_iter_nl(out_eigs)
2150
2151 ! first line -> column names
2152 call write_iter_header_start(out_eigs)
2153 do is = 1, st%d%kpt%nglobal
2154 do ii = 1, st%nst
2155 write(buf, '(a,i4)') 'Eigenvalue ',ii
2156 call write_iter_header(out_eigs, buf)
2157 end do
2158 end do
2159 call write_iter_nl(out_eigs)
2160
2161 ! second line: units
2162 call write_iter_string(out_eigs, '#[Iter n.]')
2163 call write_iter_header(out_eigs, '[' // trim(units_abbrev(units_out%time)) // ']')
2164 do is = 1, st%d%kpt%nglobal
2165 do ii = 1, st%nst
2166 call write_iter_header(out_eigs, '[' // trim(units_abbrev(units_out%energy)) // ']')
2167 end do
2168 end do
2169 call write_iter_nl(out_eigs)
2170 call td_write_print_header_end(out_eigs)
2171 end if
2172
2173 call write_iter_start(out_eigs)
2174 do is = 1, st%d%kpt%nglobal
2175 do ii =1 , st%nst
2176 call write_iter_double(out_eigs, units_from_atomic(units_out%energy, st%eigenval(ii,is)), 1)
2177 end do
2178 end do
2179 call write_iter_nl(out_eigs)
2180
2181 pop_sub(td_write_eigs)
2182 end subroutine td_write_eigs
2183
2184 ! ---------------------------------------------------------
2185 subroutine td_write_ionch(out_ionch, mesh, st, iter)
2186 type(c_ptr), intent(inout) :: out_ionch
2187 class(mesh_t), intent(in) :: mesh
2188 type(states_elec_t), intent(in) :: st
2189 integer, intent(in) :: iter
2190
2191 integer :: ii, ist, Nch, ik, idim
2192 character(len=68) :: buf
2193 real(real64), allocatable :: ch(:), occ(:)
2194 real(real64), allocatable :: occbuf(:)
2195
2196 push_sub(td_write_ionch)
2197
2198
2199 nch = st%nst * st%d%kpt%nglobal * st%d%dim
2200 safe_allocate(ch(0: nch))
2201 safe_allocate(occ(0: nch))
2202
2203 occ(:) = m_zero
2204 ii = 1
2205 do ik = 1, st%nik
2206 do ist = 1, st%nst
2207 do idim = 1, st%d%dim
2208 if (st%st_start <= ist .and. ist <= st%st_end .and. &
2209 st%d%kpt%start <= ik .and. ik <= st%d%kpt%end) then
2210 occ(ii) = st%occ(ist, ik)
2211 end if
2212 ii = ii+1
2213 end do
2214 end do
2215 end do
2216
2218 if (st%parallel_in_states) then
2219 safe_allocate(occbuf(0: nch))
2220 occbuf(:) = m_zero
2221 call st%mpi_grp%allreduce(occ(0), occbuf(0), nch+1, mpi_double_precision, mpi_sum)
2222 occ(:) = occbuf(:)
2223 safe_deallocate_a(occbuf)
2224 end if
2225
2226 !Calculate the channels
2227 call td_calc_ionch(mesh, st, ch, nch)
2228
2229
2230 if (.not. mpi_grp_is_root(mpi_world)) then
2231 safe_deallocate_a(ch)
2232 pop_sub(td_write_ionch)
2233 return ! only first node outputs
2234 end if
2235
2236
2237 if (iter == 0) then
2238 call td_write_print_header_init(out_ionch)
2239
2240 ! first line -> column names
2241 call write_iter_header_start(out_ionch)
2242
2243 do ii = 0, nch
2244 if (occ(ii)>m_zero .or. ii == 0) then
2245 write(buf, '(a,f4.1,a)') 'Pion(',occ(ii)*ii,'+, t)'
2246 call write_iter_header(out_ionch, buf)
2247 end if
2248 end do
2249 call write_iter_nl(out_ionch)
2250
2251 ! second line: units
2252 call write_iter_string(out_ionch, '#[Iter n.]')
2253 call write_iter_header(out_ionch, '[' // trim(units_abbrev(units_out%time)) // ']')
2254 do ii = 0, nch
2255 if (occ(ii)>m_zero .or. ii == 0) then
2256 call write_iter_header(out_ionch, '[' // trim(units_abbrev(unit_one)) // ']')
2257 end if
2258 end do
2259 call write_iter_nl(out_ionch)
2260 call td_write_print_header_end(out_ionch)
2261 end if
2262
2263 call write_iter_start(out_ionch)
2264 do ii =0 , nch
2265 if (occ(ii)>m_zero .or. ii == 0) then
2266 call write_iter_double(out_ionch, units_from_atomic(unit_one, ch(ii)), 1)
2267 end if
2268 end do
2269 call write_iter_nl(out_ionch)
2270
2271 safe_deallocate_a(ch)
2272 safe_deallocate_a(occ)
2273
2274 pop_sub(td_write_ionch)
2275 end subroutine td_write_ionch
2276
2277 ! ---------------------------------------------------------
2278 subroutine td_write_proj(out_proj, space, mesh, ions, st, gs_st, kick, iter)
2279 type(c_ptr), intent(inout) :: out_proj
2280 class(space_t), intent(in) :: space
2281 class(mesh_t), intent(in) :: mesh
2282 type(ions_t), intent(in) :: ions
2283 type(states_elec_t), intent(inout) :: st
2284 type(states_elec_t), intent(in) :: gs_st
2285 type(kick_t), intent(in) :: kick
2286 integer, intent(in) :: iter
2287
2288 complex(real64), allocatable :: projections(:,:,:)
2289 character(len=80) :: aux
2290 integer :: ik, ist, uist, idir
2291
2292 push_sub(td_write_proj)
2293
2294 if (iter == 0) then
2295 if (mpi_grp_is_root(mpi_world)) then
2296 call td_write_print_header_init(out_proj)
2297
2298 write(aux, '(a15,i2)') '# nspin ', st%d%nspin
2299 call write_iter_string(out_proj, aux)
2300 call write_iter_nl(out_proj)
2301
2302 call kick_write(kick, out = out_proj)
2303
2304 call write_iter_string(out_proj, "#%")
2305 call write_iter_nl(out_proj)
2306
2307 write(aux, '(a,i8)') "# nik ", st%nik
2308 call write_iter_string(out_proj, aux)
2309 call write_iter_nl(out_proj)
2310
2311 write(aux, '(a,2i8)') "# st ", gs_st%st_start, st%nst
2312 call write_iter_string(out_proj, aux)
2313 call write_iter_nl(out_proj)
2314
2315 write(aux, '(a,2i8)') "# ust ", gs_st%st_start, gs_st%st_end
2316 call write_iter_string(out_proj, aux)
2317 call write_iter_nl(out_proj)
2318
2319 do ik = 1, st%nik
2320 call write_iter_string(out_proj, "# w(ik)*occ(ist,ik) ")
2321 do ist = gs_st%st_start, st%nst
2322 call write_iter_double(out_proj, st%kweights(ik)*st%occ(ist, ik), 1)
2323 end do
2324 call write_iter_nl(out_proj)
2325 end do
2326
2327 call write_iter_header_start(out_proj)
2328 do ik = 1, st%nik
2329 do ist = gs_st%st_start, st%nst
2330 do uist = gs_st%st_start, gs_st%st_end
2331 write(aux, '(i4,a,i4)') ist, ' -> ', uist
2332 call write_iter_header(out_proj, 'Re {'//trim(aux)//'}')
2333 call write_iter_header(out_proj, 'Im {'//trim(aux)//'}')
2334 end do
2335 end do
2336 end do
2337 call write_iter_nl(out_proj)
2338
2339 end if
2340
2341 !The dipole matrix elements cannot be computed like that for solids
2342 if (.not. space%is_periodic()) then
2343
2344 safe_allocate(projections(1:st%nst, gs_st%st_start:gs_st%st_end, 1:st%nik))
2345 do idir = 1, space%dim
2346 projections = m_z0
2347
2348 call dipole_matrix_elements(idir)
2349
2350 if (mpi_grp_is_root(mpi_world)) then
2351 write(aux, '(a,i1,a)') "<i|x_", idir, "|a>"
2352 call write_iter_string(out_proj, "# ------")
2353 call write_iter_header(out_proj, aux)
2354 do ik = 1, st%nik
2355 do ist = gs_st%st_start, st%st_end
2356 do uist = gs_st%st_start, gs_st%st_end
2357 call write_iter_double(out_proj, real(projections(ist, uist, ik), real64), 1)
2358 call write_iter_double(out_proj, aimag(projections(ist, uist, ik)), 1)
2359 end do
2360 end do
2361 end do
2362 call write_iter_nl(out_proj)
2363
2364 end if
2365 end do
2366 safe_deallocate_a(projections)
2367
2368 end if
2369
2370 if (mpi_grp_is_root(mpi_world)) then
2372 end if
2373
2374 end if
2375
2376 safe_allocate(projections(1:st%nst, gs_st%st_start:gs_st%st_end, 1:st%nik))
2377 projections(:,:,:) = m_z0
2378 call calc_projections(mesh, st, gs_st, projections)
2379
2380 if (mpi_grp_is_root(mpi_world)) then
2381 call write_iter_start(out_proj)
2382 do ik = 1, st%nik
2383 do ist = gs_st%st_start, st%nst
2384 do uist = gs_st%st_start, gs_st%st_end
2385 call write_iter_double(out_proj, real(projections(ist, uist, ik), real64), 1)
2386 call write_iter_double(out_proj, aimag(projections(ist, uist, ik)), 1)
2387 end do
2388 end do
2389 end do
2390 call write_iter_nl(out_proj)
2391 end if
2392
2393 safe_deallocate_a(projections)
2394 pop_sub(td_write_proj)
2395
2396 contains
2397 ! ---------------------------------------------------------
2398 subroutine dipole_matrix_elements(dir)
2399 integer, intent(in) :: dir
2400
2401 integer :: uist, ist, ik, idim
2402 real(real64) :: n_dip(space%dim)
2403 complex(real64), allocatable :: xpsi(:,:)
2404 complex(real64), allocatable :: psi(:, :), gspsi(:, :)
2405
2407
2408 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
2409 safe_allocate(gspsi(1:mesh%np, 1:st%d%dim))
2410 safe_allocate(xpsi(1:mesh%np, 1:st%d%dim))
2411
2412 do ik = st%d%kpt%start, st%d%kpt%end
2413 do ist = st%st_start, st%st_end
2414 call states_elec_get_state(st, mesh, ist, ik, psi)
2415 do uist = gs_st%st_start, gs_st%st_end
2416 call states_elec_get_state(gs_st, mesh, uist, ik, gspsi)
2417
2418 do idim = 1, st%d%dim
2419 xpsi(1:mesh%np, idim) = mesh%x(1:mesh%np, dir)*gspsi(1:mesh%np, idim)
2420 end do
2421 projections(ist, uist, ik) = -zmf_dotp(mesh, st%d%dim, psi, xpsi, reduce = .false.)
2422
2423 end do
2424 end do
2425 end do
2426
2427 safe_deallocate_a(xpsi)
2428 safe_deallocate_a(gspsi)
2429 safe_deallocate_a(psi)
2430
2431 call comm_allreduce(st%dom_st_kpt_mpi_grp, projections)
2432
2433 ! n_dip is not defined for more than space%dim
2434 n_dip = ions%dipole()
2435 do ik = 1, st%nik
2436 do ist = gs_st%st_start, st%nst
2437 do uist = gs_st%st_start, gs_st%st_end
2438 projections(ist, uist, ik) = projections(ist, uist, ik) - n_dip(dir)
2439 end do
2440 end do
2441 end do
2442
2443
2445 end subroutine dipole_matrix_elements
2446
2447 end subroutine td_write_proj
2448
2449 ! ---------------------------------------------------------
2453 ! ---------------------------------------------------------
2454 subroutine td_write_n_ex(out_nex, outp, namespace, mesh, kpoints, st, gs_st, iter)
2455 type(c_ptr), intent(inout) :: out_nex
2456 type(output_t), intent(in) :: outp
2457 type(namespace_t), intent(in) :: namespace
2458 class(mesh_t), intent(in) :: mesh
2459 type(kpoints_t), intent(in) :: kpoints
2460 type(states_elec_t), intent(inout) :: st
2461 type(states_elec_t), intent(inout) :: gs_st
2462 integer, intent(in) :: iter
2463
2464 complex(real64), allocatable :: projections(:,:)
2465 character(len=80) :: aux, dir
2466 integer :: ik, ikpt, ist, uist, err
2467 real(real64) :: Nex, weight
2468 integer :: gs_nst
2469 real(real64), allocatable :: Nex_kpt(:)
2470
2471
2472 push_sub(td_write_n_ex)
2473
2474 if (iter == 0) then
2475 if (mpi_grp_is_root(mpi_world)) then
2476 call td_write_print_header_init(out_nex)
2477
2478 write(aux, '(a15,i2)') '# nspin ', st%d%nspin
2479 call write_iter_string(out_nex, aux)
2480 call write_iter_nl(out_nex)
2481
2482 call write_iter_string(out_nex, "#%")
2483 call write_iter_nl(out_nex)
2484
2485 write(aux, '(a,i8)') "# nik ", st%nik
2486 call write_iter_string(out_nex, aux)
2487 call write_iter_nl(out_nex)
2488
2489 write(aux, '(a,2i8)') "# st ", gs_st%st_start, st%nst
2490 call write_iter_string(out_nex, aux)
2491 call write_iter_nl(out_nex)
2492
2493 write(aux, '(a,2i8)') "# ust ", gs_st%st_start, gs_st%st_end
2494 call write_iter_string(out_nex, aux)
2495 call write_iter_nl(out_nex)
2496
2497 call write_iter_header_start(out_nex)
2498 call write_iter_header(out_nex, '# iter t Nex(t)')
2499 call write_iter_nl(out_nex)
2500
2501 end if
2502
2503 if (mpi_grp_is_root(mpi_world)) then
2504 call td_write_print_header_end(out_nex)
2505 end if
2506
2507 end if
2508
2509 !We only need the occupied GS states
2510 if (.not. st%parallel_in_states) then
2511 do ik = st%d%kpt%start, st%d%kpt%end
2512 do ist = 1, gs_st%nst
2513 if (gs_st%occ(ist, ik) > m_min_occ) gs_nst = ist
2514 end do
2515 end do
2516 else
2517 gs_nst = gs_st%nst
2518 end if
2519
2520 safe_allocate(projections(1:gs_nst, 1:st%nst))
2521
2522 safe_allocate(nex_kpt(1:st%nik))
2523 nex_kpt = m_zero
2524 do ik = st%d%kpt%start, st%d%kpt%end
2525 ikpt = st%d%get_kpoint_index(ik)
2526 call zstates_elec_calc_projections(st, gs_st, namespace, mesh, ik, projections, gs_nst)
2527 do ist = 1, gs_nst
2528 weight = st%kweights(ik) * gs_st%occ(ist, ik)/ st%smear%el_per_state
2529 do uist = st%st_start, st%st_end
2530 nex_kpt(ikpt) = nex_kpt(ikpt) - weight * st%occ(uist, ik) * abs(projections(ist, uist))**2
2531 end do
2532 end do
2533 if (st%d%ispin == spin_polarized) then
2534 nex_kpt(ikpt) = nex_kpt(ikpt) + sum(st%occ(st%st_start:st%st_end, ik))*m_half*st%kweights(ik)
2535 else
2536 nex_kpt(ikpt) = nex_kpt(ikpt) + sum(st%occ(st%st_start:st%st_end, ik))*st%kweights(ik)
2537 end if
2538 end do
2539
2540 if (st%parallel_in_states .or. st%d%kpt%parallel) then
2541 call comm_allreduce(st%st_kpt_mpi_grp, nex_kpt)
2542 end if
2543
2544 nex = sum(nex_kpt)
2545
2546 if (mpi_grp_is_root(mpi_world)) then
2547 call write_iter_start(out_nex)
2548 call write_iter_double(out_nex, nex, 1)
2549 call write_iter_nl(out_nex)
2550
2551 ! now write down the k-resolved part
2552 write(dir, '(a,a,i7.7)') trim(outp%iter_dir),"td.", iter ! name of directory
2553
2554 call io_function_output_global_bz(outp%how(option__output__current_kpt) &
2555 + outp%how(option__output__density_kpt), dir, "n_excited_el_kpt", namespace, &
2556 kpoints, nex_kpt, unit_one, err)
2557 end if
2558
2559 safe_deallocate_a(projections)
2560 safe_deallocate_a(nex_kpt)
2561
2562 pop_sub(td_write_n_ex)
2563 end subroutine td_write_n_ex
2564
2565 ! ---------------------------------------------------------
2570 ! ---------------------------------------------------------
2571 subroutine calc_projections(mesh, st, gs_st, projections)
2572 class(mesh_t), intent(in) :: mesh
2573 type(states_elec_t), intent(inout) :: st
2574 type(states_elec_t), intent(in) :: gs_st
2575 complex(real64), intent(inout) :: projections(1:st%nst, gs_st%st_start:gs_st%nst, 1:st%nik)
2576
2577 integer :: uist, ist, ik
2578 complex(real64), allocatable :: psi(:, :), gspsi(:, :)
2579 push_sub(calc_projections)
2580
2581 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
2582 safe_allocate(gspsi(1:mesh%np, 1:st%d%dim))
2583
2584 projections(:,:,:) = m_zero
2585
2586 do ik = st%d%kpt%start, st%d%kpt%end
2587 do ist = st%st_start, st%st_end
2588 call states_elec_get_state(st, mesh, ist, ik, psi)
2589 do uist = gs_st%st_start, gs_st%nst
2590 call states_elec_get_state(gs_st, mesh, uist, ik, gspsi)
2591 projections(ist, uist, ik) = zmf_dotp(mesh, st%d%dim, psi, gspsi, reduce = .false.)
2592 end do
2593 end do
2594 end do
2595
2596 safe_deallocate_a(psi)
2597 safe_deallocate_a(gspsi)
2598
2599 call comm_allreduce(st%dom_st_kpt_mpi_grp, projections)
2600
2601 pop_sub(calc_projections)
2602 end subroutine calc_projections
2603
2604
2605 subroutine td_write_proj_kp(mesh, kpoints, st, gs_st, namespace, iter)
2606 class(mesh_t), intent(in) :: mesh
2607 type(kpoints_t), intent(in) :: kpoints
2608 type(states_elec_t), intent(in) :: st
2609 type(states_elec_t), intent(inout) :: gs_st
2610 type(namespace_t), intent(in) :: namespace
2611 integer, intent(in) :: iter
2612
2613 complex(real64), allocatable :: proj(:,:), psi(:,:,:), gs_psi(:,:,:), temp_state(:,:)
2614 character(len=80) :: filename1, filename2
2615 integer :: ik,ist, jst, file, idim, nk_proj
2616
2617 push_sub(td_write_proj_kp)
2618
2619 write(filename1,'(I10)') iter
2620 filename1 = 'td.general/projections_iter_'//trim(adjustl(filename1))
2621 file = 9845623
2622
2623 safe_allocate(proj(1:gs_st%nst, 1:gs_st%nst))
2624 safe_allocate(psi(1:gs_st%nst,1:gs_st%d%dim,1:mesh%np))
2625 safe_allocate(gs_psi(1:gs_st%nst,1:gs_st%d%dim,1:mesh%np))
2626 safe_allocate(temp_state(1:mesh%np,1:gs_st%d%dim))
2627
2628 ! Project only k-points that have a zero weight.
2629 ! Why? It is unlikely that one is interested in the projections
2630 ! of the Monkhorst-Pack kpoints, but instead we assume that
2631 ! the user has specified a k-path with zero weights
2632 nk_proj = kpoints%nik_skip
2633
2634 do ik = kpoints%reduced%npoints-nk_proj+1, kpoints%reduced%npoints
2635 ! reset arrays
2636 psi(1:gs_st%nst, 1:gs_st%d%dim, 1:mesh%np)= m_zero
2637 gs_psi(1:gs_st%nst, 1:gs_st%d%dim, 1:mesh%np)= m_zero
2638 ! open file for writing
2639 if (mpi_world%rank == 0) then
2640 write(filename2,'(I10)') ik
2641 filename2 = trim(adjustl(filename1))//'_ik_'//trim(adjustl(filename2))
2642 file = io_open(filename2, namespace, action='write')
2643 end if
2644 ! get all states at ik that are locally stored (ground state and td-states)
2645 do ist=gs_st%st_start,gs_st%st_end
2646 if (state_kpt_is_local(gs_st, ist, ik)) then
2647 call states_elec_get_state(st, mesh, ist, ik,temp_state)
2648 do idim = 1,gs_st%d%dim
2649 psi(ist,idim,1:mesh%np) = temp_state(1:mesh%np,idim)
2650 end do
2651 call states_elec_get_state(gs_st, mesh, ist, ik, temp_state)
2652 do idim = 1,gs_st%d%dim
2653 gs_psi(ist,idim,1:mesh%np) = temp_state(1:mesh%np,idim)
2654 end do
2655 end if
2656 end do
2657 ! collect states at ik from all processes in one array
2658 call comm_allreduce(mpi_world, psi)
2659 call comm_allreduce(mpi_world, gs_psi)
2660
2661 ! compute the overlaps as a matrix product
2662 assert(mesh%np_global*gs_st%d%dim < huge(0_int32))
2663 proj(1:gs_st%nst, 1:gs_st%nst) = m_zero
2664 call zgemm('n', &
2665 'c', &
2666 gs_st%nst, &
2667 gs_st%nst, &
2668 i8_to_i4(mesh%np_global*gs_st%d%dim), &
2669 cmplx(mesh%volume_element, m_zero, real64) , &
2670 psi(1, 1, 1), &
2671 ubound(psi, dim = 1), &
2672 gs_psi(1, 1, 1), &
2673 ubound(gs_psi, dim = 1), &
2674 m_z0, &
2675 proj(1, 1), &
2676 ubound(proj, dim = 1))
2677
2678 ! write to file
2679 if (mpi_world%rank == 0) then
2680 do ist = 1, gs_st%nst
2681 do jst = 1, gs_st%nst
2682 write(file,'(I3,1x,I3,1x,e13.6,1x,e13.6,2x)') ist, jst, proj(ist,jst)
2683 end do
2684 end do
2685 call io_close(file)
2686 end if
2687
2688 end do! ik
2689
2690 safe_deallocate_a(proj)
2691 safe_deallocate_a(psi)
2692 safe_deallocate_a(gs_psi)
2693 safe_deallocate_a(temp_state)
2694
2695 pop_sub(td_write_proj_kp)
2696 end subroutine td_write_proj_kp
2697
2698 !---------------------------------------
2699 subroutine td_write_floquet(namespace, space, hm, ext_partners, mesh, st, iter)
2700 type(namespace_t), intent(in) :: namespace
2701 class(space_t), intent(in) :: space
2702 type(hamiltonian_elec_t), intent(inout) :: hm
2703 type(partner_list_t), intent(in) :: ext_partners
2704 class(mesh_t), intent(in) :: mesh
2705 type(states_elec_t), intent(inout) :: st
2706 integer, intent(in) :: iter
2707
2708 complex(real64), allocatable :: hmss(:,:), psi(:,:,:), hpsi(:,:,:), temp_state1(:,:)
2709 complex(real64), allocatable :: HFloquet(:,:,:), HFloq_eff(:,:), temp(:,:)
2710 real(real64), allocatable :: eigenval(:), bands(:,:)
2711 character(len=80) :: filename
2712 integer :: it, nT, ik, ist, in, im, file, idim, nik, ik_count
2713 integer :: Forder, Fdim, m0, n0, n1, nst, ii, jj, lim_nst
2714 logical :: downfolding
2715 type(states_elec_t) :: hm_st
2716
2717 real(real64) :: dt, Tcycle, omega
2718
2719 push_sub(td_write_floquet)
2720
2721 downfolding = .false.
2722
2723 ! this does not depend on propagation, so we do it only once
2724 if (.not. iter == 0) then
2725 pop_sub(td_write_floquet)
2726 return
2727 end if
2728
2729 nst = st%nst
2730
2731 !for now no domain distributionallowed
2732 assert(mesh%np == mesh%np_global)
2733
2734 ! this is used to initialize the hpsi (more effiecient ways?)
2735 call states_elec_copy(hm_st, st)
2736
2737 !%Variable TDFloquetFrequency
2738 !%Type float
2739 !%Default 0
2740 !%Section Time-Dependent::TD Output
2741 !%Description
2742 !% Frequency for the Floquet analysis, this should be the carrier frequency or integer multiples of it.
2743 !% Other options will work, but likely be nonsense.
2744 !%
2745 !%End
2746 call parse_variable(namespace, 'TDFloquetFrequency', m_zero, omega, units_inp%energy)
2747 call messages_print_var_value('Frequency used for Floquet analysis', omega, namespace=namespace)
2748 if (abs(omega) <= m_epsilon) then
2749 message(1) = "Please give a non-zero value for TDFloquetFrequency"
2750 call messages_fatal(1, namespace=namespace)
2751 end if
2752
2753 ! get time of one cycle
2754 tcycle = m_two * m_pi / omega
2755
2756 !%Variable TDFloquetSample
2757 !%Type integer
2758 !%Default 20
2759 !%Section Time-Dependent::TD Output
2760 !%Description
2761 !% Number of points on which one Floquet cycle is sampled in the time-integral of the Floquet analysis.
2762 !%
2763 !%End
2764 call parse_variable(namespace, 'TDFloquetSample',20 ,nt)
2765 call messages_print_var_value('Number of Floquet time-sampling points', nt, namespace=namespace)
2766 dt = tcycle/real(nt, real64)
2767
2768 !%Variable TDFloquetDimension
2769 !%Type integer
2770 !%Default -1
2771 !%Section Time-Dependent::TD Output
2772 !%Description
2773 !% Order of Floquet Hamiltonian. If negative number is given, downfolding is performed.
2774 !%End
2775 call parse_variable(namespace, 'TDFloquetDimension',-1,forder)
2776 if (forder .ge. 0) then
2777 call messages_print_var_value('Order of multiphoton Floquet-Hamiltonian', forder, namespace=namespace)
2778 !Dimension of multiphoton Floquet-Hamiltonian
2779 fdim = 2 * forder + 1
2780 else
2781 message(1) = 'Floquet-Hamiltonian is downfolded'
2782 call messages_info(1, namespace=namespace)
2783 downfolding = .true.
2784 forder = 1
2785 fdim = 3
2786 end if
2787
2788 dt = tcycle/real(nt, real64)
2789
2790 ! we are only interested for k-point with zero weight
2791 nik = hm%kpoints%nik_skip
2793 safe_allocate(hmss(1:nst,1:nst))
2794 safe_allocate( psi(1:nst,1:st%d%dim,1:mesh%np))
2795 safe_allocate(hpsi(1:nst,1:st%d%dim,1:mesh%np))
2796 safe_allocate(temp_state1(1:mesh%np,1:st%d%dim))
2797
2798 ! multiphoton Floquet Hamiltonian, layout:
2799 ! (H_{-n,-m} ... H_{-n,0} ... H_{-n,m})
2800 ! ( . . . . . )
2801 ! H = (H_{0,-m} ... H_{0,0} ... H_{0,m} )
2802 ! ( . . . . . )
2803 ! (H_{n,-m} ... H_{n,0} ... H_{n,m} )
2804 safe_allocate(hfloquet(1:nik,1:nst*fdim, 1:nst*fdim))
2805 hfloquet(1:nik,1:nst*fdim, 1:nst*fdim) = m_zero
2806
2807 ! perform time-integral over one cycle
2808 do it = 1, nt
2809 ! get non-interacting Hamiltonian at time (offset by one cycle to allow for ramp)
2810 call hm%update(mesh, namespace, space, ext_partners, time=tcycle+it*dt)
2811 ! get hpsi
2812 call zhamiltonian_elec_apply_all(hm, namespace, mesh, st, hm_st)
2813
2814 ! project Hamiltonian into grounstates for zero weight k-points
2815 ik_count = 0
2816
2817 do ik = hm%kpoints%reduced%npoints-nik+1, hm%kpoints%reduced%npoints
2818 ik_count = ik_count + 1
2819
2820 psi(1:nst, 1:st%d%dim, 1:mesh%np)= m_zero
2821 hpsi(1:nst, 1:st%d%dim, 1:mesh%np)= m_zero
2822
2823 do ist = st%st_start, st%st_end
2824 if (state_kpt_is_local(st, ist, ik)) then
2825 call states_elec_get_state(st, mesh, ist, ik,temp_state1)
2826 do idim = 1, st%d%dim
2827 psi(ist, idim, 1:mesh%np) = temp_state1(1:mesh%np,idim)
2828 end do
2829 call states_elec_get_state(hm_st, mesh, ist, ik,temp_state1)
2830 do idim = 1, st%d%dim
2831 hpsi(ist, idim,1:mesh%np) = temp_state1(1:mesh%np,idim)
2832 end do
2833 end if
2834 end do
2835 call comm_allreduce(mpi_world, psi)
2836 call comm_allreduce(mpi_world, hpsi)
2837 assert(mesh%np_global*st%d%dim < huge(0_int32))
2838 hmss(1:nst,1:nst) = m_zero
2839 call zgemm( 'n', &
2840 'c', &
2841 nst, &
2842 nst, &
2843 i8_to_i4(mesh%np_global*st%d%dim), &
2844 cmplx(mesh%volume_element, m_zero, real64) , &
2845 hpsi(1, 1, 1), &
2846 ubound(hpsi, dim = 1), &
2847 psi(1, 1, 1), &
2848 ubound(psi, dim = 1), &
2849 m_z0, &
2850 hmss(1, 1), &
2851 ubound(hmss, dim = 1))
2852
2853 hmss(1:nst,1:nst) = conjg(hmss(1:nst,1:nst))
2854
2855 ! accumulate the Floqeut integrals
2856 do in = -forder, forder
2857 do im = -forder, forder
2858 ii = (in+forder) * nst
2859 jj = (im+forder) * nst
2860 hfloquet(ik_count, ii+1:ii+nst, jj+1:jj+nst) = &
2861 hfloquet(ik_count, ii+1:ii+nst, jj+1:jj+nst) + hmss(1:nst, 1:nst) * exp(-(in-im)*m_zi*omega*it*dt)
2862 ! diagonal term
2863 if (in == im) then
2864 do ist = 1, nst
2865 hfloquet(ik_count, ii+ist, ii+ist) = hfloquet(ik_count, ii+ist, ii+ist) + in*omega
2866 end do
2867 end if
2868 end do
2869 end do
2870 end do !ik
2871
2872 end do ! it
2873
2874 hfloquet(:,:,:) = m_one/nt*hfloquet(:,:,:)
2875
2876 ! diagonalize Floquet Hamiltonian
2877 if (downfolding) then
2878 ! here perform downfolding
2879 safe_allocate(hfloq_eff(1:nst,1:nst))
2880 safe_allocate(eigenval(1:nst))
2881 safe_allocate(bands(1:nik,1:nst))
2882
2883 hfloq_eff(1:nst,1:nst) = m_zero
2884 do ik = 1, nik
2885 ! the HFloquet blocks are copied directly out of the super matrix
2886 m0 = nst ! the m=0 start position
2887 n0 = nst ! the n=0 start postion
2888 n1 = 2*nst ! the n=+1 start postion
2889 hfloq_eff(1:nst, 1:nst) = hfloquet(ik, n0+1:n0+nst, m0+1:m0+nst) + &
2890 m_one/omega*(matmul(hfloquet(ik, 1:nst, m0+1:m0+nst), hfloquet(ik, n1+1:n1+nst, m0+1:m0+nst))- &
2891 matmul(hfloquet(ik, n1+1:n1+nst, m0+1:m0+nst), hfloquet(ik, 1:nst, m0+1:m0+nst)))
2892
2893 call lalg_eigensolve(nst, hfloq_eff, eigenval)
2894 bands(ik,1:nst) = eigenval(1:nst)
2895 end do
2896 safe_deallocate_a(hfloq_eff)
2897 else
2898 ! the full Floquet
2899 safe_allocate(eigenval(1:nst*fdim))
2900 safe_allocate(bands(1:nik,1:nst*fdim))
2901 safe_allocate(temp(1:nst*fdim, 1:nst*fdim))
2902
2903 do ik = 1, nik
2904 temp(1:nst*fdim, 1:nst*fdim) = hfloquet(ik, 1:nst*fdim, 1:nst*fdim)
2905 call lalg_eigensolve(nst*fdim, temp, eigenval)
2906 bands(ik, 1:nst*fdim) = eigenval(1:nst*fdim)
2907 end do
2908 end if
2909
2910 !write bandstructure to file
2911 if (downfolding) then
2912 lim_nst = nst
2913 filename = "downfolded_floquet_bands"
2914 else
2915 lim_nst = nst*fdim
2916 filename = "floquet_bands"
2917 end if
2918 ! write bands (full or downfolded)
2919 if (mpi_world%rank == 0) then
2920 file = 987254
2921 file = io_open(filename, namespace, action = 'write')
2922 do ik = 1,nik
2923 do ist = 1,lim_nst
2924 write(file,'(e13.6, 1x)',advance='no') bands(ik,ist)
2925 end do
2926 write(file,'(1x)')
2927 end do
2928 call io_close(file)
2929 end if
2930
2931 if (.not. downfolding) then
2932 ! for the full Floquet case compute also the trivially shifted
2933 ! Floquet bands for reference (i.e. setting H_{nm}=0 for n!=m)
2934 bands(1:nik, 1:nst*fdim) = m_zero
2935 do ik = 1, nik
2936 temp(1:nst*fdim,1:nst*fdim) = m_zero
2937 do jj = 0, fdim - 1
2938 ii = jj * nst
2939 temp(ii+1:ii+nst, ii+1:ii+nst) = hfloquet(ik, ii+1:ii+nst, ii+1:ii+nst)
2940 end do
2941 call lalg_eigensolve(nst*fdim, temp, eigenval)
2942 bands(ik, 1:nst*fdim) = eigenval(1:nst*fdim)
2943 end do
2944
2945 if (mpi_world%rank == 0) then
2946 filename = 'trivial_floquet_bands'
2947 file = io_open(filename, namespace, action = 'write')
2948 do ik=1,nik
2949 do ist = 1,lim_nst
2950 write(file,'(e13.6, 1x)', advance='no') bands(ik,ist)
2951 end do
2952 write(file,'(1x)')
2953 end do
2954 call io_close(file)
2955 end if
2956 end if
2957
2958 ! reset time in Hamiltonian
2959 call hm%update(mesh, namespace, space, ext_partners, time=m_zero)
2960
2961 safe_deallocate_a(hmss)
2962 safe_deallocate_a(psi)
2963 safe_deallocate_a(hpsi)
2964 safe_deallocate_a(temp_state1)
2965 safe_deallocate_a(hfloquet)
2966 safe_deallocate_a(eigenval)
2967 safe_deallocate_a(bands)
2968 safe_deallocate_a(temp)
2969
2970 pop_sub(td_write_floquet)
2971
2972 end subroutine td_write_floquet
2973
2974 ! ---------------------------------------------------------
2975 subroutine td_write_total_current(out_total_current, space, mesh, st, iter)
2976 type(c_ptr), intent(inout) :: out_total_current
2977 class(space_t), intent(in) :: space
2978 class(mesh_t), intent(in) :: mesh
2979 type(states_elec_t), intent(in) :: st
2980 integer, intent(in) :: iter
2981
2982 integer :: idir, ispin
2983 character(len=50) :: aux
2984 real(real64) :: total_current(space%dim), abs_current(space%dim)
2985
2986 push_sub(td_write_total_current)
2987
2988 if (mpi_grp_is_root(mpi_world) .and. iter == 0) then
2989 call td_write_print_header_init(out_total_current)
2990
2991 ! first line: column names
2992 call write_iter_header_start(out_total_current)
2993
2994 do idir = 1, space%dim
2995 write(aux, '(a2,i1,a1)') 'I(', idir, ')'
2996 call write_iter_header(out_total_current, aux)
2997 end do
2998
2999 do idir = 1, space%dim
3000 write(aux, '(a10,i1,a1)') 'IntAbs(j)(', idir, ')'
3001 call write_iter_header(out_total_current, aux)
3002 end do
3003
3004 do ispin = 1, st%d%nspin
3005 do idir = 1, space%dim
3006 write(aux, '(a4,i1,a1,i1,a1)') 'I-sp', ispin, '(', idir, ')'
3007 call write_iter_header(out_total_current, aux)
3008 end do
3009 end do
3010
3011 call write_iter_nl(out_total_current)
3012
3013 call td_write_print_header_end(out_total_current)
3014 end if
3015
3016 assert(allocated(st%current))
3017
3018 if (mpi_grp_is_root(mpi_world)) then
3019 call write_iter_start(out_total_current)
3020 end if
3021
3022 total_current = 0.0_real64
3023 do idir = 1, space%dim
3024 do ispin = 1, st%d%spin_channels
3025 total_current(idir) = total_current(idir) + dmf_integrate(mesh, st%current(:, idir, ispin), reduce = .false.)
3026 end do
3027 total_current(idir) = units_from_atomic(units_out%length/units_out%time, total_current(idir))
3028 end do
3029 if (mesh%parallel_in_domains) then
3030 call mesh%allreduce(total_current, dim = space%dim)
3031 end if
3032
3033 abs_current = 0.0_real64
3034 do idir = 1, space%dim
3035 do ispin = 1, st%d%spin_channels
3036 abs_current(idir) = abs_current(idir) + dmf_integrate(mesh, abs(st%current(:, idir, ispin)), reduce = .false.)
3037 end do
3038 abs_current(idir) = units_from_atomic(units_out%length/units_out%time, abs_current(idir))
3039 end do
3040 if (mesh%parallel_in_domains) then
3041 call mesh%allreduce(abs_current, dim = space%dim)
3042 end if
3043
3044 if (mpi_grp_is_root(mpi_world)) then
3045 call write_iter_double(out_total_current, total_current, space%dim)
3046 call write_iter_double(out_total_current, abs_current, space%dim)
3047 end if
3048
3049 do ispin = 1, st%d%nspin
3050 total_current = 0.0_real64
3051 do idir = 1, space%dim
3052 total_current(idir) = units_from_atomic(units_out%length/units_out%time, &
3053 dmf_integrate(mesh, st%current(:, idir, ispin), reduce = .false.))
3054 end do
3055 if (mesh%parallel_in_domains) then
3056 call mesh%allreduce(total_current, dim = space%dim)
3057 end if
3058 if (mpi_grp_is_root(mpi_world)) then
3059 call write_iter_double(out_total_current, total_current, space%dim)
3060 end if
3061 end do
3062
3063 if (mpi_grp_is_root(mpi_world)) then
3064 call write_iter_nl(out_total_current)
3065 end if
3066
3067 pop_sub(td_write_total_current)
3069
3070 ! ---------------------------------------------------------
3071
3072 subroutine td_write_total_heat_current(write_obj, space, hm, gr, st, iter)
3073 type(c_ptr), intent(inout) :: write_obj
3074 class(space_t), intent(in) :: space
3075 type(hamiltonian_elec_t), intent(inout) :: hm
3076 type(grid_t), intent(in) :: gr
3077 type(states_elec_t), intent(in) :: st
3078 integer, intent(in) :: iter
3079
3080 integer :: idir, ispin
3081 character(len=50) :: aux
3082 real(real64), allocatable :: heat_current(:, :, :)
3083 real(real64) :: total_current(space%dim)
3084
3085 push_sub(td_write_total_current)
3086
3087 if (mpi_grp_is_root(mpi_world) .and. iter == 0) then
3088 call td_write_print_header_init(write_obj)
3089
3090 ! first line: column names
3091 call write_iter_header_start(write_obj)
3092
3093 do idir = 1, space%dim
3094 write(aux, '(a2,i1,a1)') 'Jh(', idir, ')'
3095 call write_iter_header(write_obj, aux)
3096 end do
3097
3098 call write_iter_nl(write_obj)
3099
3100 call td_write_print_header_end(write_obj)
3101 end if
3102
3103 safe_allocate(heat_current(1:gr%np, 1:space%dim, 1:st%d%nspin))
3104
3105 call current_heat_calculate(space, gr%der, hm, st, heat_current)
3106
3107 if (mpi_grp_is_root(mpi_world)) call write_iter_start(write_obj)
3108
3109 total_current = 0.0_real64
3110 do idir = 1, space%dim
3111 do ispin = 1, st%d%spin_channels
3112 total_current(idir) = total_current(idir) + dmf_integrate(gr, heat_current(:, idir, ispin))
3113 end do
3114 total_current(idir) = units_from_atomic(units_out%energy*units_out%length/units_out%time, total_current(idir))
3115 end do
3116
3117 safe_deallocate_a(heat_current)
3118
3119 if (mpi_grp_is_root(mpi_world)) call write_iter_double(write_obj, total_current, space%dim)
3120
3121 if (mpi_grp_is_root(mpi_world)) call write_iter_nl(write_obj)
3122
3123 pop_sub(td_write_total_current)
3124 end subroutine td_write_total_heat_current
3125
3126
3127 ! ---------------------------------------------------------
3128 subroutine td_write_partial_charges(out_partial_charges, mesh, st, ions, iter)
3129 type(c_ptr), intent(inout) :: out_partial_charges
3130 class(mesh_t), intent(in) :: mesh
3131 type(states_elec_t), intent(in) :: st
3132 type(ions_t), intent(in) :: ions
3133 integer, intent(in) :: iter
3134
3135 integer :: idir
3136 character(len=50) :: aux
3137 real(real64), allocatable :: hirshfeld_charges(:)
3138
3139 push_sub(td_write_partial_charges)
3140
3141 safe_allocate(hirshfeld_charges(1:ions%natoms))
3142
3143 call partial_charges_calculate(mesh, st, ions, hirshfeld_charges)
3144
3145 if (mpi_grp_is_root(mpi_world)) then
3146
3147 if (iter == 0) then
3148
3149 call td_write_print_header_init(out_partial_charges)
3150
3151 ! first line: column names
3152 call write_iter_header_start(out_partial_charges)
3153
3154 do idir = 1, ions%natoms
3155 write(aux, '(a13,i3,a1)') 'hirshfeld(atom=', idir, ')'
3156 call write_iter_header(out_partial_charges, aux)
3157 end do
3158
3159 call write_iter_nl(out_partial_charges)
3160
3161 call td_write_print_header_end(out_partial_charges)
3162 end if
3163
3164 call write_iter_start(out_partial_charges)
3166 call write_iter_double(out_partial_charges, hirshfeld_charges, ions%natoms)
3167
3168 call write_iter_nl(out_partial_charges)
3169 end if
3170
3171 safe_deallocate_a(hirshfeld_charges)
3172
3174 end subroutine td_write_partial_charges
3175
3176 ! ---------------------------------------------------------
3177 subroutine td_write_q(out_q, space, ks, iter)
3178 type(c_ptr), intent(inout) :: out_q
3179 class(space_t), intent(in) :: space
3180 type(v_ks_t), intent(in) :: ks
3181 integer, intent(in) :: iter
3182
3183 integer :: ii
3184 character(len=50) :: aux
3185
3186 push_sub(td_write_q)
3187
3188 if (mpi_grp_is_root(mpi_world)) then
3189 if (iter == 0) then
3190 call td_write_print_header_init(out_q)
3191 call write_iter_header_start(out_q)
3192 do ii = 1, ks%pt%nmodes
3193 write(aux, '(a1,i3,a3)') 'q', ii, '(t)'
3194 call write_iter_header(out_q, aux)
3195 end do
3196 do ii = 1, ks%pt%nmodes
3197 write(aux, '(a1,i3,a3)') 'p', ii, '(t)'
3198 call write_iter_header(out_q, aux)
3199 end do
3200 do ii = 1, space%dim
3201 write(aux, '(a3,i3,a3)') 'f_pt', ii, '(t)'
3202 call write_iter_header(out_q, aux)
3203 end do
3204 call write_iter_nl(out_q)
3205 call td_write_print_header_end(out_q)
3206 end if
3207
3208 call write_iter_start(out_q)
3209 call write_iter_double(out_q, ks%pt_mx%pt_q, ks%pt%nmodes)
3210 call write_iter_double(out_q, ks%pt_mx%pt_p, ks%pt%nmodes)
3211 call write_iter_double(out_q, ks%pt_mx%fmf, space%dim)
3212 call write_iter_nl(out_q)
3213 end if
3214
3215 pop_sub(td_write_q)
3216 end subroutine td_write_q
3217
3218
3219 ! ---------------------------------------------------------
3220 subroutine td_write_mxll_field(out_mxll, space, hm, dt, iter)
3221 type(c_ptr), intent(inout) :: out_mxll
3222 class(space_t), intent(in) :: space
3223 type(hamiltonian_elec_t),intent(in) :: hm
3224 real(real64), intent(in) :: dt
3225 integer, intent(in) :: iter
3226
3227 integer :: idir
3228 real(real64) :: field(space%dim)
3229 character(len=80) :: aux
3230 character(len=1) :: field_char
3231
3232 push_sub(td_write_mxll_field)
3233
3234 if (.not. mpi_grp_is_root(mpi_world)) then
3235 pop_sub(td_write_mxll_field)
3236 return ! only first node outputs
3237 end if
3238
3239 if (iter == 0) then
3240 call td_write_print_header_init(out_mxll)
3241
3242 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, dt), &
3243 " [", trim(units_abbrev(units_out%time)), "]"
3244 call write_iter_string(out_mxll, aux)
3245 call write_iter_nl(out_mxll)
3246
3247 call write_iter_header_start(out_mxll)
3248 select case (hm%mxll%coupling_mode)
3249 case (length_gauge_dipole, multipolar_expansion)
3250 if (hm%mxll%add_electric_dip) field_char = 'E'
3251 if (hm%mxll%add_magnetic_dip) field_char = 'B'
3252 do idir = 1, space%dim
3253 write(aux, '(a,i1,a)') field_char // '(', idir, ')'
3254 call write_iter_header(out_mxll, aux)
3255 end do
3256 case (velocity_gauge_dipole)
3257 do idir = 1, space%dim
3258 write(aux, '(a,i1,a)') 'A(', idir, ')'
3259 call write_iter_header(out_mxll, aux)
3260 end do
3261 end select
3262 call write_iter_nl(out_mxll)
3263
3264 call write_iter_string(out_mxll, '#[Iter n.]')
3265 call write_iter_header(out_mxll, '[' // trim(units_abbrev(units_out%time)) // ']')
3266
3267 ! Note that we do not print out units of E, A or B, but rather units of e*E, e*A or e*B
3268 ! (force, energy and magnetic flux density, respectively).
3269 select case (hm%mxll%coupling_mode)
3270 case (length_gauge_dipole, multipolar_expansion)
3271 if (hm%mxll%add_electric_dip) aux = '[' // trim(units_abbrev(units_out%force)) // ']'
3272 if (hm%mxll%add_magnetic_dip) aux = '[' // trim(units_abbrev(unit_one/units_out%length**2)) // ']'
3273 do idir = 1, space%dim
3274 call write_iter_header(out_mxll, aux)
3275 end do
3276 case (velocity_gauge_dipole)
3277 aux = '[' // trim(units_abbrev(units_out%energy)) // ']'
3278 do idir = 1, space%dim
3279 call write_iter_header(out_mxll, aux)
3280 end do
3281 end select
3282 call write_iter_nl(out_mxll)
3283 call td_write_print_header_end(out_mxll)
3284 end if
3285
3286 call write_iter_start(out_mxll)
3287
3288 field = m_zero
3289 select case (hm%mxll%coupling_mode)
3290 case (length_gauge_dipole, multipolar_expansion)
3291 if (hm%mxll%add_electric_dip) field = units_from_atomic(units_out%force, hm%mxll%e_field_dip)
3292 if (hm%mxll%add_magnetic_dip) field = units_from_atomic(unit_one/units_out%length**2, hm%mxll%b_field_dip)
3293 call write_iter_double(out_mxll, field, space%dim)
3294 case (velocity_gauge_dipole)
3295 field = units_from_atomic(units_out%energy, hm%mxll%vec_pot_dip)
3296 call write_iter_double(out_mxll, field, space%dim)
3297 end select
3298 call write_iter_nl(out_mxll)
3299
3300 pop_sub(td_write_mxll_field)
3301 end subroutine td_write_mxll_field
3302
3303
3304 ! ---------------------------------------------------------
3305 subroutine td_write_effective_u(out_coords, lda_u, iter)
3306 type(c_ptr), intent(inout) :: out_coords
3307 type(lda_u_t), intent(in) :: lda_u
3308 integer, intent(in) :: iter
3309
3310 integer :: ios, inn
3311 character(len=50) :: aux
3312
3313 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
3314
3315 push_sub(td_write_effective_u)
3316
3317 if (iter == 0) then
3318 call td_write_print_header_init(out_coords)
3319
3320 ! first line: column names
3321 call write_iter_header_start(out_coords)
3322
3323 do ios = 1, lda_u%norbsets
3324 write(aux, '(a2,i3,a1)') 'Ueff(', ios, ')'
3325 call write_iter_header(out_coords, aux)
3326 end do
3327
3328 do ios = 1, lda_u%norbsets
3329 write(aux, '(a2,i3,a1)') 'U(', ios, ')'
3330 call write_iter_header(out_coords, aux)
3331 end do
3332
3333 do ios = 1, lda_u%norbsets
3334 write(aux, '(a2,i3,a1)') 'J(', ios, ')'
3335 call write_iter_header(out_coords, aux)
3336 end do
3337
3338 if (lda_u%intersite) then
3339 do ios = 1, lda_u%norbsets
3340 do inn = 1, lda_u%orbsets(ios)%nneighbors
3341 write(aux, '(a2,i3,a1,i3,a1)') 'V(', ios,'-', inn, ')'
3342 call write_iter_header(out_coords, aux)
3343 end do
3344 end do
3345 end if
3346
3347
3348 call write_iter_nl(out_coords)
3349
3350 ! second line: units
3351 call write_iter_string(out_coords, '#[Iter n.]')
3352 call write_iter_header(out_coords, '[' // trim(units_abbrev(units_out%time)) // ']')
3353 call write_iter_string(out_coords, &
3354 'Effective U ' // trim(units_abbrev(units_out%energy)) // &
3355 ', U in '// trim(units_abbrev(units_out%energy)) // &
3356 ', J in ' // trim(units_abbrev(units_out%energy)))
3357 call write_iter_nl(out_coords)
3358
3359 call td_write_print_header_end(out_coords)
3360 end if
3361
3362 call write_iter_start(out_coords)
3363
3364 do ios = 1, lda_u%norbsets
3365 call write_iter_double(out_coords, units_from_atomic(units_out%energy, &
3366 lda_u%orbsets(ios)%Ueff), 1)
3367 end do
3368
3369 do ios = 1, lda_u%norbsets
3370 call write_iter_double(out_coords, units_from_atomic(units_out%energy, &
3371 lda_u%orbsets(ios)%Ubar), 1)
3372 end do
3373
3374 do ios = 1, lda_u%norbsets
3375 call write_iter_double(out_coords, units_from_atomic(units_out%energy, &
3376 lda_u%orbsets(ios)%Jbar), 1)
3377 end do
3378
3379 if (lda_u%intersite) then
3380 do ios = 1, lda_u%norbsets
3381 do inn = 1, lda_u%orbsets(ios)%nneighbors
3382 call write_iter_double(out_coords, units_from_atomic(units_out%energy, &
3383 lda_u%orbsets(ios)%V_ij(inn,0)), 1)
3384 end do
3385 end do
3386 end if
3387
3388 call write_iter_nl(out_coords)
3389
3390 pop_sub(td_write_effective_u)
3391 end subroutine td_write_effective_u
3392
3394 subroutine td_write_norm_ks_orbitals(file_handle, grid, kpoints, st, iter)
3395 type(c_ptr), intent(inout) :: file_handle
3396 type(grid_t), intent(in) :: grid
3397 type(kpoints_t), intent(in) :: kpoints
3398 type(states_elec_t), intent(in) :: st
3399 integer, intent(in) :: iter
3400
3401 integer :: ik_ispin, ist
3402 character(len=7) :: nkpt_str, nst_str
3403 character(len=7) :: ik_str, ist_str
3404 real(real64), allocatable :: norm_ks(:, :)
3405 real(real64) :: n_electrons
3406
3408
3409 safe_allocate(norm_ks(1:st%nst, 1:st%nik))
3410 call states_elec_calc_norms(grid, kpoints, st, norm_ks)
3411
3412 if (mpi_grp_is_root(mpi_world)) then
3413 ! Header
3414 if (iter == 0) then
3415 call td_write_print_header_init(file_handle)
3416
3417 ! Line 1
3418 write(nkpt_str, '(I7)') st%nik
3419 write(nst_str, '(I7)') st%nst
3420 call write_iter_string(file_handle, '# Dimensions. (nstates, nkpt * nspin):')
3421 call write_iter_string(file_handle, trim(adjustl(nst_str)) // ' ' // trim(adjustl(nkpt_str)))
3422 call write_iter_nl(file_handle)
3423
3424 ! Line 2
3425 call write_iter_string(file_handle, '# Norm ordering: (istate, ikpoint_spin)')
3426 call write_iter_nl(file_handle)
3427
3428 ! Line 3
3429 call write_iter_header_start(file_handle)
3430 call write_iter_header(file_handle, 'N_electrons')
3431 do ik_ispin = 1, st%nik
3432 do ist = 1, st%nst
3433 write(ik_str, '(I7)') ik_ispin
3434 write(ist_str, '(I7)') ist
3435 call write_iter_header(file_handle, &
3436 'Norm (' // trim(ist_str) // ',' // trim(ik_str) // ')')
3437 enddo
3438 enddo
3439 call write_iter_nl(file_handle)
3440 call td_write_print_header_end(file_handle)
3441 end if
3442
3443 n_electrons = sum(st%occ * norm_ks**2)
3444
3445 ! Output norms for time step `iter`
3446 call write_iter_start(file_handle)
3447 call write_iter_double(file_handle, n_electrons, 1)
3448 do ik_ispin = 1, st%nik
3449 call write_iter_double(file_handle, norm_ks(:, ik_ispin), size(norm_ks, 1))
3450 enddo
3451 call write_iter_nl(file_handle)
3452
3453 end if
3454
3455 safe_deallocate_a(norm_ks)
3456
3458
3459 end subroutine td_write_norm_ks_orbitals
3460
3461 ! ---------------------------------------------------------
3462 subroutine td_write_mxll_init(writ, namespace, iter, dt)
3463 type(td_write_t), intent(out) :: writ
3464 type(namespace_t), intent(in) :: namespace
3465 integer, intent(in) :: iter
3466 real(real64), intent(in) :: dt
3467
3468 integer :: default, flags, iout, first
3469
3470 push_sub(td_write_mxll_init)
3471
3472 !%Variable MaxwellTDOutput
3473 !%Type flag
3474 !%Default maxwell_energy
3475 !%Section Maxwell::Output
3476 !%Description
3477 !% Defines what should be output during the time-dependent
3478 !% Maxwell simulation. Many of the options can increase the computational
3479 !% cost of the simulation, so only use the ones that you need. In
3480 !% most cases the default value is enough, as it is adapted to the
3481 !% details of the TD run.
3482 !% WARNING: the calculation of the longitudinal or transverse E and B fields
3483 !% can be very expensive, so please consider using the MaxwellOutput block
3484 !% to calculate and output these quantities at certain timesteps.
3485 !%Option maxwell_total_e_field 1
3486 !% Output of the total (longitudinal plus transverse) electric field at
3487 !% the points specified in the MaxwellFieldsCoordinate block
3488 !%Option maxwell_total_b_field 8
3489 !% Output of the total (longitudinal plus transverse) magnetic field at
3490 !% the points specified in the MaxwellFieldsCoordinate block
3491 !%Option maxwell_longitudinal_e_field 64
3492 !% Output of the longitudinal electric field at the points
3493 !% specified in the MaxwellFieldsCoordinate block (can slow down the run)
3494 !%Option maxwell_longitudinal_b_field 512
3495 !% Output of the longitudinal magnetic field at the points
3496 !% specified in the MaxwellFieldsCoordinate block (can slow down the run)
3497 !%Option maxwell_transverse_e_field 4096
3498 !% Output of the transverse electric field at the points
3499 !% specified in the MaxwellFieldsCoordinate block (can slow down the run)
3500 !%Option maxwell_transverse_b_field 32768
3501 !% Output of the transverse magnetic field at the points
3502 !% specified in the MaxwellFieldsCoordinate block (can slow down the run)
3503 !%Option maxwell_energy 262144
3504 !% Output of the electromagnetic field energy into the folder <tt>td.general/maxwell</tt>.
3505 !% WARNING: the transverse and longitudinal energies will be correct only if you request
3506 !% the longitudinal and transverse E or B fields as output. Otherwise they will be set to
3507 !% zero.
3508 !%Option e_field_surface_x 524288
3509 !% Output of the E field sliced along the plane x=0 for each field component
3510 !%Option e_field_surface_y 1048576
3511 !% Output of the E field sliced along the plane y=0 for each field component
3512 !%Option e_field_surface_z 2097152
3513 !% Output of the E field sliced along the plane z=0 for each field component
3514 !%Option b_field_surface_x 4194304
3515 !% Output of the B field sliced along the plane x=0 for each field component
3516 !%Option b_field_surface_y 8388608
3517 !% Output of the B field sliced along the plane y=0 for each field component
3518 !%Option b_field_surface_z 16777216
3519 !% Output of the B field sliced along the plane z=0 for each field component
3520 !%End
3521
3522 default = 2**(out_maxwell_energy - 1)
3523 call parse_variable(namespace, 'MaxwellTDOutput', default, flags)
3524
3525 if (.not. varinfo_valid_option('MaxwellTDOutput', flags, is_flag = .true.)) then
3526 call messages_input_error(namespace, 'MaxwellTDOutput')
3527 end if
3528
3530 writ%out(iout)%write = (iand(flags, 2**(iout - 1)) /= 0)
3531 if (writ%out(iout)%write) then
3532 writ%out(iout + 1)%write = .true.
3533 writ%out(iout + 2)%write = .true.
3534 end if
3535 end do
3536
3538 writ%out(iout)%write = (iand(flags, 2**(iout - 1)) /= 0)
3539 end do
3540
3541 if (iter == 0) then
3542 first = 0
3543 else
3544 first = iter + 1
3545 end if
3546
3547 call io_mkdir('td.general', namespace)
3548
3549 ! total E field
3550 if (writ%out(out_maxwell_total_e_field)%write) then
3551 call write_iter_init(writ%out(out_maxwell_total_e_field)%handle, first, &
3552 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_e_field_x", namespace)))
3553 call write_iter_init(writ%out(out_maxwell_total_e_field + 1)%handle, first, &
3554 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_e_field_y", namespace)))
3555 call write_iter_init(writ%out(out_maxwell_total_e_field + 2)%handle, first, &
3556 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_e_field_z", namespace)))
3557 end if
3558
3559 ! total B field
3560 if (writ%out(out_maxwell_total_b_field)%write) then
3561 call write_iter_init(writ%out(out_maxwell_total_b_field)%handle, first, &
3562 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_b_field_x", namespace)))
3563 call write_iter_init(writ%out(out_maxwell_total_b_field + 1)%handle, first, &
3564 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_b_field_y", namespace)))
3565 call write_iter_init(writ%out(out_maxwell_total_b_field + 2)%handle, first, &
3566 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/total_b_field_z", namespace)))
3567 end if
3568
3569 ! longitudinal E field
3570 if (writ%out(out_maxwell_long_e_field)%write) then
3571 call write_iter_init(writ%out(out_maxwell_long_e_field)%handle, first, &
3572 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_e_field_x", namespace)))
3573 call write_iter_init(writ%out(out_maxwell_long_e_field + 1)%handle, first, &
3574 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_e_field_y", namespace)))
3575 call write_iter_init(writ%out(out_maxwell_long_e_field + 2)%handle, first, &
3576 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_e_field_z", namespace)))
3577 end if
3578
3579 ! longitudinal B field
3580 if (writ%out(out_maxwell_long_b_field)%write) then
3581 call write_iter_init(writ%out(out_maxwell_long_b_field)%handle, first, &
3582 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_b_field_x", namespace)))
3583 call write_iter_init(writ%out(out_maxwell_long_b_field + 1)%handle, first, &
3584 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_b_field_y", namespace)))
3585 call write_iter_init(writ%out(out_maxwell_long_b_field + 2)%handle, first, &
3586 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/longitudinal_b_field_z", namespace)))
3587 end if
3588
3589 ! transverse E field
3590 if (writ%out(out_maxwell_trans_e_field)%write) then
3591 call write_iter_init(writ%out(out_maxwell_trans_e_field)%handle, first, &
3592 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_e_field_x", namespace)))
3593 call write_iter_init(writ%out(out_maxwell_trans_e_field + 1)%handle, first, &
3594 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_e_field_y", namespace)))
3595 call write_iter_init(writ%out(out_maxwell_trans_e_field + 2)%handle, first, &
3596 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_e_field_z", namespace)))
3597 end if
3598
3599 ! transverse B field
3600 if (writ%out(out_maxwell_trans_b_field)%write) then
3601 call write_iter_init(writ%out(out_maxwell_trans_b_field)%handle, first, &
3602 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_b_field_x", namespace)))
3603 call write_iter_init(writ%out(out_maxwell_trans_b_field + 1)%handle, first, &
3604 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_b_field_y", namespace)))
3605 call write_iter_init(writ%out(out_maxwell_trans_b_field + 2)%handle, first, &
3606 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/transverse_b_field_z", namespace)))
3607 end if
3608
3609 ! Maxwell energy
3610 if (writ%out(out_maxwell_energy)%write) then
3611 call write_iter_init(writ%out(out_maxwell_energy)%handle, first, &
3612 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/maxwell_energy", namespace)))
3613 end if
3614
3615 if (writ%out(out_e_field_surface_x)%write) then
3616 call write_iter_init(writ%out(out_e_field_surface_x)%handle, first, &
3617 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/electric_field_surface-x", namespace)))
3618 end if
3619
3620 if (writ%out(out_e_field_surface_y)%write) then
3621 call write_iter_init(writ%out(out_e_field_surface_y)%handle, first, &
3622 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/electric_field_surface-y", namespace)))
3623 end if
3624
3625 if (writ%out(out_e_field_surface_z)%write) then
3626 call write_iter_init(writ%out(out_e_field_surface_z)%handle, first, &
3627 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/electric_field_surface-z", namespace)))
3628 end if
3629
3630 if (writ%out(out_b_field_surface_x)%write) then
3631 call write_iter_init(writ%out(out_b_field_surface_x)%handle, first, &
3632 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/magnetic_field_surface-x", namespace)))
3633 end if
3634
3635 if (writ%out(out_b_field_surface_y)%write) then
3636 call write_iter_init(writ%out(out_b_field_surface_y)%handle, first, &
3637 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/magnetic_field_surface-y", namespace)))
3638 end if
3639
3640 if (writ%out(out_b_field_surface_z)%write) then
3641 call write_iter_init(writ%out(out_b_field_surface_z)%handle, first, &
3642 units_from_atomic(units_out%time, dt), trim(io_workpath("td.general/magnetic_field_surface-z", namespace)))
3643 end if
3644
3645 pop_sub(td_write_mxll_init)
3646 end subroutine td_write_mxll_init
3647
3648
3649 ! ---------------------------------------------------------
3650 subroutine td_write_mxll_end(writ)
3651 type(td_write_t), intent(inout) :: writ
3652
3653 integer :: iout
3654
3655 push_sub(td_write_mxll_end)
3656
3657 do iout = 1, out_maxwell_max
3658 if (writ%out(iout)%write) call write_iter_end(writ%out(iout)%handle)
3659 end do
3660
3661 pop_sub(td_write_mxll_end)
3662 end subroutine td_write_mxll_end
3663
3664
3665 ! ---------------------------------------------------------
3666 subroutine td_write_mxll_iter(writ, space, gr, st, hm, helmholtz, dt, iter, namespace)
3667 type(td_write_t), intent(inout) :: writ
3668 class(space_t), intent(in) :: space
3669 type(grid_t), intent(inout) :: gr
3670 type(states_mxll_t), intent(inout) :: st
3671 type(hamiltonian_mxll_t), intent(inout) :: hm
3672 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
3673 real(real64), intent(in) :: dt
3674 integer, intent(in) :: iter
3675 type(namespace_t), intent(in) :: namespace
3676
3677
3678 push_sub(td_write_mxll_iter)
3679
3680 call profiling_in("TD_WRITE_ITER_MAXWELL")
3681
3682 if (writ%out(out_maxwell_trans_e_field)%write .or. writ%out(out_maxwell_trans_b_field)%write) then
3683 call helmholtz%get_trans_field(namespace, st%rs_state_trans, total_field=st%rs_state)
3684 call get_rs_state_at_point(st%selected_points_rs_state_trans(:,:), st%rs_state_trans, &
3685 st%selected_points_coordinate(:,:), st, gr)
3686 !TODO: calculate transverse energy
3687 else
3688 hm%energy%energy_trans = m_zero
3689 end if
3690
3691 if (writ%out(out_maxwell_long_e_field)%write .or. writ%out(out_maxwell_long_b_field)%write) then
3692 call helmholtz%get_long_field(namespace, st%rs_state_long, total_field=st%rs_state)
3693 call get_rs_state_at_point(st%selected_points_rs_state_long(:,:), st%rs_state_long, &
3694 st%selected_points_coordinate(:,:), st, gr)
3695 !TODO: calculate longitudinal energy
3696 else
3697 hm%energy%energy_long = m_zero
3698 end if
3699
3700 ! total E field
3701 if (writ%out(out_maxwell_total_e_field)%write) then
3702 call td_write_fields(writ%out(out_maxwell_total_e_field)%handle, space, st, iter, dt, &
3704 call td_write_fields(writ%out(out_maxwell_total_e_field + 1)%handle, space, st, iter, dt, &
3706 call td_write_fields(writ%out(out_maxwell_total_e_field + 2)%handle, space, st, iter, dt, &
3708 end if
3709
3710 ! total B field
3711 if (writ%out(out_maxwell_total_b_field)%write) then
3712 call td_write_fields(writ%out(out_maxwell_total_b_field)%handle, space, st, iter, dt, &
3714 call td_write_fields(writ%out(out_maxwell_total_b_field + 1)%handle, space, st, iter, dt, &
3716 call td_write_fields(writ%out(out_maxwell_total_b_field + 2)%handle, space, st, iter, dt, &
3718 end if
3719
3720 ! Longitudinal E field
3721 if (writ%out(out_maxwell_long_e_field)%write) then
3722 call td_write_fields(writ%out(out_maxwell_long_e_field)%handle, space, st, iter, dt, &
3724 call td_write_fields(writ%out(out_maxwell_long_e_field + 1)%handle, space, st, iter, dt, &
3726 call td_write_fields(writ%out(out_maxwell_long_e_field + 2)%handle, space, st, iter, dt, &
3728 end if
3729
3730 ! Longitudinal B field
3731 if (writ%out(out_maxwell_long_b_field)%write) then
3732 call td_write_fields(writ%out(out_maxwell_long_b_field)%handle, space, st, iter, dt, &
3734 call td_write_fields(writ%out(out_maxwell_long_b_field + 1)%handle, space, st, iter, dt, &
3736 call td_write_fields(writ%out(out_maxwell_long_b_field + 2)%handle, space, st, iter, dt, &
3738 end if
3739
3740 ! Transverse E field
3741 if (writ%out(out_maxwell_trans_e_field)%write) then
3742 call td_write_fields(writ%out(out_maxwell_trans_e_field)%handle, space, st, iter, dt, &
3744 call td_write_fields(writ%out(out_maxwell_trans_e_field + 1)%handle, space, st, iter, dt, &
3746 call td_write_fields(writ%out(out_maxwell_trans_e_field + 2)%handle, space, st, iter, dt, &
3748 end if
3749
3750 ! Transverse B field
3751 if (writ%out(out_maxwell_trans_b_field)%write) then
3752 call td_write_fields(writ%out(out_maxwell_trans_b_field)%handle, space, st, iter, dt, &
3754 call td_write_fields(writ%out(out_maxwell_trans_b_field + 1)%handle, space, st, iter, dt, &
3756 call td_write_fields(writ%out(out_maxwell_trans_b_field + 2)%handle, space, st, iter, dt, &
3758 end if
3760 ! Maxwell energy
3761 if (writ%out(out_maxwell_energy)%write) then
3762 call td_write_maxwell_energy(writ%out(out_maxwell_energy)%handle, hm, iter)
3763 end if
3764
3765 if (writ%out(out_e_field_surface_x)%write) then
3766 call td_write_electric_field_box_surface(writ%out(out_e_field_surface_x)%handle, st, 1, iter)
3767 end if
3768
3769 if (writ%out(out_e_field_surface_y)%write) then
3770 call td_write_electric_field_box_surface(writ%out(out_e_field_surface_y)%handle, st, 2, iter)
3771 end if
3772
3773 if (writ%out(out_e_field_surface_z)%write) then
3774 call td_write_electric_field_box_surface(writ%out(out_e_field_surface_z)%handle, st, 3, iter)
3775 end if
3776
3777 if (writ%out(out_b_field_surface_x)%write) then
3778 call td_write_magnetic_field_box_surface(writ%out(out_b_field_surface_x)%handle, st, 1, iter)
3779 end if
3780
3781 if (writ%out(out_b_field_surface_y)%write) then
3782 call td_write_magnetic_field_box_surface(writ%out(out_b_field_surface_y)%handle, st, 2, iter)
3783 end if
3784
3785 if (writ%out(out_b_field_surface_z)%write) then
3786 call td_write_magnetic_field_box_surface(writ%out(out_b_field_surface_z)%handle, st, 3, iter)
3787 end if
3788
3789 call profiling_out("TD_WRITE_ITER_MAXWELL")
3790
3791 pop_sub(td_write_mxll_iter)
3792 end subroutine td_write_mxll_iter
3793
3794
3795 ! ---------------------------------------------------------
3796 subroutine td_write_maxwell_energy(out_maxwell_energy, hm, iter)
3797 type(c_ptr), intent(inout) :: out_maxwell_energy
3798 type(hamiltonian_mxll_t), intent(in) :: hm
3799 integer, intent(in) :: iter
3800
3801 integer :: ii
3802
3803 integer :: n_columns
3804
3805 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
3806
3807 push_sub(td_write_maxwell_energy)
3808
3809 n_columns = 8
3810
3811 if (iter == 0) then
3812 call td_write_print_header_init(out_maxwell_energy)
3813
3814 ! first line -> column names
3815 call write_iter_header_start(out_maxwell_energy)
3816 call write_iter_header(out_maxwell_energy, 'Total')
3817 call write_iter_header(out_maxwell_energy, 'E**2')
3818 call write_iter_header(out_maxwell_energy, 'B**2')
3819 call write_iter_header(out_maxwell_energy, 'Total+Boundaries')
3820 call write_iter_header(out_maxwell_energy, 'Boundaries')
3821 call write_iter_header(out_maxwell_energy, 'Transversal')
3822 call write_iter_header(out_maxwell_energy, 'Longitudinal')
3823 call write_iter_header(out_maxwell_energy, 'Incident Waves')
3824
3825 call write_iter_nl(out_maxwell_energy)
3826
3827 ! units
3828
3829 call write_iter_string(out_maxwell_energy, '#[Iter n.]')
3830 call write_iter_header(out_maxwell_energy, '[' // trim(units_abbrev(units_out%time)) // ']')
3831
3832 do ii = 1, n_columns
3833 call write_iter_header(out_maxwell_energy, '[' // trim(units_abbrev(units_out%energy)) // ']')
3834 end do
3835 call write_iter_nl(out_maxwell_energy)
3836
3837 call td_write_print_header_end(out_maxwell_energy)
3838 end if
3839
3840 call write_iter_start(out_maxwell_energy)
3841 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%energy), 1)
3842 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%e_energy), 1)
3843 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%b_energy), 1)
3844 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, &
3845 hm%energy%energy+hm%energy%boundaries), 1)
3846 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%boundaries), 1)
3847 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%energy_trans), 1)
3848 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%energy_long), 1)
3849 call write_iter_double(out_maxwell_energy, units_from_atomic(units_out%energy, hm%energy%energy_plane_waves), 1)
3850 call write_iter_nl(out_maxwell_energy)
3851
3853 end subroutine td_write_maxwell_energy
3854
3855
3856 ! ---------------------------------------------------------
3857 subroutine td_write_electric_field_box_surface(out_field_surf, st, dim, iter)
3858 type(c_ptr), intent(inout) :: out_field_surf
3859 type(states_mxll_t), intent(in) :: st
3860 integer, intent(in) :: dim
3861 integer, intent(in) :: iter
3862
3863 integer :: ii
3864
3865 integer :: n_columns
3866
3867 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
3868
3870
3871 n_columns = 12
3872
3873 if (iter == 0) then
3874 call td_write_print_header_init(out_field_surf)
3875
3876 ! first line -> column names
3877 call write_iter_header_start(out_field_surf)
3878 call write_iter_header(out_field_surf, '- x direction')
3879 call write_iter_header(out_field_surf, '+ x direction')
3880 call write_iter_header(out_field_surf, '- y direction')
3881 call write_iter_header(out_field_surf, '+ y direction')
3882 call write_iter_header(out_field_surf, '- z direction')
3883 call write_iter_header(out_field_surf, '+ z direction')
3884 call write_iter_header(out_field_surf, '- x dir. p. w.')
3885 call write_iter_header(out_field_surf, '+ x dir. p. w.')
3886 call write_iter_header(out_field_surf, '- y dir. p. w.')
3887 call write_iter_header(out_field_surf, '+ y dir. p. w.')
3888 call write_iter_header(out_field_surf, '- z dir. p. w.')
3889 call write_iter_header(out_field_surf, '+ z dir. p. w.')
3890
3891 call write_iter_nl(out_field_surf)
3892
3893 ! units
3894 call write_iter_string(out_field_surf, '#[Iter n.]')
3895 call write_iter_header(out_field_surf, '[' // trim(units_abbrev(units_out%time)) // ']')
3896
3897 do ii = 1, n_columns
3898 call write_iter_header(out_field_surf, '[' // trim(units_abbrev(units_out%energy/units_out%length)) // ']')
3899 end do
3900 call write_iter_nl(out_field_surf)
3901
3902 call td_write_print_header_end(out_field_surf)
3903 end if
3904
3905 call write_iter_start(out_field_surf)
3906 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3907 st%electric_field_box_surface(1,1,dim)), 1)
3908 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3909 st%electric_field_box_surface(2,1,dim)), 1)
3910 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3911 st%electric_field_box_surface(1,2,dim)), 1)
3912 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3913 st%electric_field_box_surface(2,2,dim)), 1)
3914 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3915 st%electric_field_box_surface(1,3,dim)), 1)
3916 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3917 st%electric_field_box_surface(2,3,dim)), 1)
3918 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3919 st%electric_field_box_surface_plane_waves(1,1,dim)), 1)
3920 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3921 st%electric_field_box_surface_plane_waves(2,1,dim)), 1)
3922 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3923 st%electric_field_box_surface_plane_waves(1,2,dim)), 1)
3924 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3925 st%electric_field_box_surface_plane_waves(2,2,dim)), 1)
3926 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3927 st%electric_field_box_surface_plane_waves(1,3,dim)), 1)
3928 call write_iter_double(out_field_surf, units_from_atomic(units_out%energy/units_out%length, &
3929 st%electric_field_box_surface_plane_waves(2,3,dim)), 1)
3930 call write_iter_nl(out_field_surf)
3931
3934
3935
3936 ! ---------------------------------------------------------
3937 subroutine td_write_magnetic_field_box_surface(out_field_surf, st, dim, iter)
3938 type(c_ptr), intent(inout) :: out_field_surf
3939 type(states_mxll_t), intent(in) :: st
3940 integer, intent(in) :: dim
3941 integer, intent(in) :: iter
3942
3943 integer :: ii
3944
3945 integer :: n_columns
3946
3947 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
3948
3951 n_columns = 12
3952
3953 if (iter == 0) then
3954 call td_write_print_header_init(out_field_surf)
3955
3956 ! first line -> column names
3957 call write_iter_header_start(out_field_surf)
3958 call write_iter_header(out_field_surf, '- x direction')
3959 call write_iter_header(out_field_surf, '+ x direction')
3960 call write_iter_header(out_field_surf, '- y direction')
3961 call write_iter_header(out_field_surf, '+ y direction')
3962 call write_iter_header(out_field_surf, '- z direction')
3963 call write_iter_header(out_field_surf, '+ z direction')
3964 call write_iter_header(out_field_surf, '- x dir. p. w.')
3965 call write_iter_header(out_field_surf, '+ x dir. p. w.')
3966 call write_iter_header(out_field_surf, '- y dir. p. w.')
3967 call write_iter_header(out_field_surf, '+ y dir. p. w.')
3968 call write_iter_header(out_field_surf, '- z dir. p. w.')
3969 call write_iter_header(out_field_surf, '+ z dir. p. w.')
3970
3971 call write_iter_nl(out_field_surf)
3972
3973 ! units
3974 call write_iter_string(out_field_surf, '#[Iter n.]')
3975 call write_iter_header(out_field_surf, '[' // trim(units_abbrev(units_out%time)) // ']')
3976
3977 do ii = 1, n_columns
3978 call write_iter_header(out_field_surf, '[' // trim(units_abbrev(unit_one/units_out%length**2)) // ']')
3979 end do
3980 call write_iter_nl(out_field_surf)
3981
3982 call td_write_print_header_end(out_field_surf)
3983 end if
3984
3985 call write_iter_start(out_field_surf)
3986 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3987 st%magnetic_field_box_surface(1,1,dim)), 1)
3988 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3989 st%magnetic_field_box_surface(2,1,dim)), 1)
3990 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3991 st%magnetic_field_box_surface(1,2,dim)), 1)
3992 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3993 st%magnetic_field_box_surface(2,2,dim)), 1)
3994 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3995 st%magnetic_field_box_surface(1,3,dim)), 1)
3996 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3997 st%magnetic_field_box_surface(2,3,dim)), 1)
3998 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
3999 st%magnetic_field_box_surface_plane_waves(1,1,dim)), 1)
4000 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
4001 st%magnetic_field_box_surface_plane_waves(2,1,dim)), 1)
4002 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
4003 st%magnetic_field_box_surface_plane_waves(1,2,dim)), 1)
4004 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
4005 st%magnetic_field_box_surface_plane_waves(2,2,dim)), 1)
4006 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
4007 st%magnetic_field_box_surface_plane_waves(1,3,dim)), 1)
4008 call write_iter_double(out_field_surf, units_from_atomic(unit_one/units_out%length**2, &
4009 st%magnetic_field_box_surface_plane_waves(2,3,dim)), 1)
4010 call write_iter_nl(out_field_surf)
4011
4014
4015 ! ---------------------------------------------------------
4016 subroutine td_write_fields(out_fields, space, st, iter, dt, e_or_b_field, field_type, idir)
4017 type(c_ptr), intent(inout) :: out_fields
4018 class(space_t), intent(in) :: space
4019 type(states_mxll_t), intent(in) :: st
4020 integer, intent(in) :: iter
4021 real(real64), intent(in) :: dt
4022 integer, intent(in) :: e_or_b_field
4023 integer, intent(in) :: field_type
4024 integer, intent(in) :: idir
4025
4026
4027 integer :: id
4028 real(real64) :: field(space%dim), selected_field
4029 character(len=80) :: aux
4031 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
4032
4033 push_sub(td_write_fields)
4034
4035 if (iter == 0) then
4036 call td_write_print_header_init(out_fields)
4037
4038 ! first line
4039 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, dt), &
4040 " [", trim(units_abbrev(units_out%time)), "]"
4041 call write_iter_string(out_fields, aux)
4042 call write_iter_nl(out_fields)
4043
4044 call write_iter_header_start(out_fields)
4045
4046 do id = 1, st%selected_points_number
4047 select case (e_or_b_field)
4048 case (maxwell_e_field)
4049 write(aux, '(a,i1,a)') 'E(', id, ')'
4050 case (maxwell_b_field)
4051 write(aux, '(a,i1,a)') 'B(', id, ')'
4052 end select
4053 call write_iter_header(out_fields, aux)
4054 end do
4055
4056 call write_iter_nl(out_fields)
4057 call write_iter_string(out_fields, '#[Iter n.]')
4058 call write_iter_header(out_fields, ' [' // trim(units_abbrev(units_out%time)) // ']')
4059
4060 ! Note that we do not print out units of E, B, or A, but rather units of e*E, e*B, e*A.
4061 ! (force, force, and energy, respectively). The reason is that the units of E, B or A
4062 ! are ugly.
4063 aux = ' [' // trim(units_abbrev(units_out%force)) // ']'
4064 do id = 1, st%selected_points_number
4065 call write_iter_header(out_fields, aux)
4066 end do
4067 call write_iter_nl(out_fields)
4068 call td_write_print_header_end(out_fields)
4069 end if
4070
4071 call write_iter_start(out_fields)
4072
4073 do id = 1, st%selected_points_number
4074 select case (e_or_b_field)
4075 case (maxwell_e_field)
4076 ! Output of electric field at selected point
4077 select case (field_type)
4078 case (maxwell_total_field)
4079 call get_electric_field_vector(st%selected_points_rs_state(:,id), field(1:st%dim))
4080 case (maxwell_long_field)
4081 call get_electric_field_vector(st%selected_points_rs_state_long(:,id), field(1:st%dim))
4082 case (maxwell_trans_field)
4083 call get_electric_field_vector(st%selected_points_rs_state_trans(:,id), field(1:st%dim))
4084 end select
4085 selected_field = units_from_atomic(units_out%energy/units_out%length, field(idir))
4086 case (maxwell_b_field)
4087 ! Output of magnetic field at selected point
4088 select case (field_type)
4089 case (maxwell_total_field)
4090 call get_magnetic_field_vector(st%selected_points_rs_state(:,id), st%rs_sign, field(1:st%dim))
4091 case (maxwell_long_field)
4092 call get_magnetic_field_vector(st%selected_points_rs_state_long(:,id), st%rs_sign, field(1:st%dim))
4093 case (maxwell_trans_field)
4094 call get_magnetic_field_vector(st%selected_points_rs_state_trans(:,id), st%rs_sign, field(1:st%dim))
4095 end select
4096 selected_field = units_from_atomic(unit_one/units_out%length**2, field(idir))
4097 end select
4098 call write_iter_double(out_fields, selected_field, 1)
4099 end do
4100
4101 call write_iter_nl(out_fields)
4102
4103 pop_sub(td_write_fields)
4104 end subroutine td_write_fields
4105
4106
4107 !----------------------------------------------------------
4108 subroutine td_write_mxll_free_data(writ, namespace, space, gr, st, hm, helmholtz, outp, iter, time)
4109 type(td_write_t), intent(inout) :: writ
4110 type(namespace_t), intent(in) :: namespace
4111 class(space_t), intent(in) :: space
4112 type(grid_t), intent(inout) :: gr
4113 type(states_mxll_t), intent(inout) :: st
4114 type(hamiltonian_mxll_t), intent(inout) :: hm
4115 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
4116 type(output_t), intent(in) :: outp
4117 integer, intent(in) :: iter
4118 real(real64), intent(in) :: time
4119
4120 character(len=256) :: filename
4121
4122 push_sub(td_write_maxwell_free_data)
4123 call profiling_in("TD_WRITE_MAXWELL_DATA")
4124
4125 ! now write down the rest
4126 write(filename, '(a,a,i7.7)') trim(outp%iter_dir),"td.", iter ! name of directory
4127
4128 call output_mxll(outp, namespace, space, gr, st, hm, helmholtz, time, filename)
4129
4130 call profiling_out("TD_WRITE_MAXWELL_DATA")
4131 pop_sub(td_write_maxwell_free_data)
4132 end subroutine td_write_mxll_free_data
4133
4134end module td_write_oct_m
4135
4136!! Local Variables:
4137!! mode: f90
4138!! coding: utf-8
4139!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:170
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:185
Sets the iteration number to the C object.
Definition: write_iter.F90:174
Writes to the corresponding file and adds one to the iteration. Must be called after write_iter_init(...
Definition: write_iter.F90:167
double exp(double __x) __attribute__((__nothrow__
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:118
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:608
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public spinors
integer, parameter, public spin_polarized
subroutine, public excited_states_kill(excited_state)
Kills an excited_state structure.
subroutine, public excited_states_init(excited_state, ground_state, filename, namespace)
Fills in an excited_state structure, by reading a file called "filename". This file describes the "pr...
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
logical function, public list_has_lasers(partners)
type(lasers_t) function, pointer, public list_get_lasers(partners)
subroutine, public gauge_field_output_write(this, out_gauge, iter)
real(real64), parameter, public m_two
Definition: global.F90:189
real(real64), parameter, public m_zero
Definition: global.F90:187
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public lmm_r_single_atom
Default local magnetic moments sphere radius for an isolated system.
Definition: global.F90:215
complex(real64), parameter, public m_zi
Definition: global.F90:201
integer, parameter, public max_output_types
Definition: global.F90:148
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public m_one
Definition: global.F90:188
real(real64), parameter, public m_min_occ
Minimal occupation that is considered to be non-zero.
Definition: global.F90:210
This module implements the underlying real-space grid.
Definition: grid.F90:117
The Helmholtz decomposition is intended to contain "only mathematical" functions and procedures to co...
This module defines classes and functions for interaction partners.
subroutine, public zio_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.
subroutine, public io_function_read_what_how_when(namespace, space, what, how, output_interval, what_tag_in, how_tag_in, output_interval_tag_in, ignore_error)
Definition: io.F90:114
subroutine, public io_close(iunit, grp)
Definition: io.F90:468
character(len=max_path_len) function, public io_workpath(path, namespace)
Definition: io.F90:313
subroutine, public io_rm(fname, namespace)
Definition: io.F90:385
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:354
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:395
real(real64) function, public ion_dynamics_temperature(ions)
This function returns the ionic temperature in energy units.
integer, parameter, public qkickmode_cos
Definition: kick.F90:169
integer, parameter, public qkickmode_none
Definition: kick.F90:169
integer, parameter, public qkickmode_sin
Definition: kick.F90:169
subroutine, public kick_function_get(space, mesh, kick, kick_function, iq, to_interpolate)
Definition: kick.F90:993
subroutine, public kick_write(kick, iunit, out)
Definition: kick.F90:891
integer, parameter, public qkickmode_bessel
Definition: kick.F90:169
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
Definition: lasers.F90:1146
subroutine, public lasers_set_nondipole_parameters(this, ndfield, nd_integration_time)
Set parameters for nondipole SFA calculation.
Definition: lasers.F90:748
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:735
integer, parameter, public e_field_electric
Definition: lasers.F90:176
integer, parameter, public e_field_vector_potential
Definition: lasers.F90:176
integer, parameter, public e_field_scalar_potential
Definition: lasers.F90:176
integer pure elemental function, public laser_kind(laser)
Definition: lasers.F90:711
subroutine, public laser_field(laser, field, time)
Retrieves the value of either the electric or the magnetic field. If the laser is given by a scalar p...
Definition: lasers.F90:1111
integer, parameter, public e_field_magnetic
Definition: lasers.F90:176
integer, parameter, public dft_u_none
Definition: lda_u.F90:200
integer, parameter, public dft_u_acbn0
Definition: lda_u.F90:200
subroutine, public magnetic_local_moments(mesh, st, ions, boundaries, rho, rr, lmm)
Definition: magnetic.F90:265
subroutine, public magnetic_moment(mesh, st, rho, mm)
Definition: magnetic.F90:183
subroutine, public magnetic_total_magnetization(mesh, st, qq, trans_mag)
Definition: magnetic.F90:334
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
Definition: math.F90:372
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:116
This module defines various routines, operating on mesh functions.
complex(real64) function, public zmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
subroutine, public dmf_multipoles(mesh, ff, lmax, multipole, mask)
This routine calculates the multipoles of a function ff.
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
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
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
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:723
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1097
subroutine, public modelmb_sym_all_states(space, mesh, st)
This module contains some common usage patterns of MPI routines.
Definition: mpi_lib.F90:115
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 handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
integer, parameter, public velocity_gauge_dipole
this module contains the output system
Definition: output_low.F90:115
subroutine, public output_modelmb(outp, namespace, space, dir, gr, ions, iter, st)
this module contains the output system
Definition: output.F90:115
subroutine, public output_all(outp, namespace, space, dir, gr, ions, iter, st, hm, ks)
Definition: output.F90:491
subroutine, public output_scalar_pot(outp, namespace, space, dir, mesh, ions, ext_partners, time)
Definition: output.F90:2532
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
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_proj
Definition: restart.F90:229
integer, parameter, public restart_type_load
Definition: restart.F90:225
subroutine, public restart_end(restart)
Definition: restart.F90:720
subroutine, public zstates_elec_matrix(st1, st2, mesh, aa)
subroutine, public zstates_elec_calc_projections(st, gs_st, namespace, mesh, ik, proj, gs_nst)
This routine computes the projection between two set of states.
This module handles spin dimensions of the states and the k-point distribution.
logical function, public state_kpt_is_local(st, ist, ik)
check whether a given state (ist, ik) is on the local node
subroutine, public states_elec_end(st)
finalize the states_elec_t object
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.
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
subroutine, public states_elec_look(restart, nik, dim, nst, ierr)
Reads the 'states' file in the restart directory, and finds out the nik, dim, and nst contained in it...
This module handles reading and writing restart information for the states_elec_t.
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 td_calc_tacc(namespace, space, gr, ions, ext_partners, st, hm, acc, time)
Electronic acceleration (to calculate harmonic spectrum...) It is calculated as:
Definition: td_calc.F90:165
subroutine, public td_calc_ionch(mesh, st, ch, Nch)
Multiple ionization probabilities calculated form the KS orbital densities C. Ullrich,...
Definition: td_calc.F90:308
subroutine, public td_calc_tvel(elec_me, kpoints, vel)
Electronic velocity (to calculate harmonic spectrum...) It is calculated as:
Definition: td_calc.F90:278
subroutine, public td_write_coordinates(out_coords, natoms, space, pos, vel, tot_forces, iter)
subroutine, public td_write_sep_coordinates(out_coords, natoms, space, pos, vel, tot_forces, iter, which)
subroutine, public td_write_print_header_init(out)
subroutine, public td_write_print_header_end(out)
subroutine td_write_magnetic_field_box_surface(out_field_surf, st, dim, iter)
Definition: td_write.F90:4031
integer, parameter, public out_total_current
Definition: td_write.F90:201
integer, parameter maxwell_b_field
Definition: td_write.F90:297
integer, parameter, public out_maxwell_max
Definition: td_write.F90:289
subroutine td_write_proj(out_proj, space, mesh, ions, st, gs_st, kick, iter)
Definition: td_write.F90:2372
integer, parameter, public out_q
Definition: td_write.F90:201
integer, parameter, public out_mxll_field
Definition: td_write.F90:201
subroutine calc_projections(mesh, st, gs_st, projections)
This subroutine calculates:
Definition: td_write.F90:2665
integer, parameter out_b_field_surface_y
Definition: td_write.F90:274
subroutine td_write_ionch(out_ionch, mesh, st, iter)
Definition: td_write.F90:2279
integer, parameter, public out_tot_m
Definition: td_write.F90:201
integer, parameter, public out_norm_ks
Definition: td_write.F90:201
integer, parameter out_maxwell_trans_b_field
Definition: td_write.F90:274
subroutine td_write_multipole_r(out_multip, space, mesh, ions, st, lmax, kick, rho, iter, mpi_grp)
Write multipoles to the corresponding file.
Definition: td_write.F90:1563
integer, parameter, public out_proj
Definition: td_write.F90:201
integer, parameter, public out_partial_charges
Definition: td_write.F90:201
integer, parameter, public out_separate_coords
Definition: td_write.F90:201
subroutine td_write_total_current(out_total_current, space, mesh, st, iter)
Definition: td_write.F90:3069
subroutine, public td_write_output(namespace, space, gr, st, hm, ks, outp, ions, ext_partners, iter, dt)
Definition: td_write.F90:1228
subroutine td_write_effective_u(out_coords, lda_u, iter)
Definition: td_write.F90:3399
integer, parameter maxwell_trans_field
Definition: td_write.F90:292
subroutine td_write_acc(out_acc, namespace, space, gr, ions, st, hm, ext_partners, dt, iter)
Definition: td_write.F90:1914
subroutine, public td_write_mxll_init(writ, namespace, iter, dt)
Definition: td_write.F90:3556
subroutine, public td_write_mxll_end(writ)
Definition: td_write.F90:3744
subroutine td_write_mxll_field(out_mxll, space, hm, dt, iter)
Definition: td_write.F90:3314
integer, parameter out_b_field_surface_x
Definition: td_write.F90:274
integer, parameter out_maxwell_long_e_field
Definition: td_write.F90:274
integer, parameter, public out_kp_proj
Definition: td_write.F90:201
integer, parameter, public out_magnets
Definition: td_write.F90:201
subroutine td_write_multipole(out_multip, space, gr, ions, st, lmax, kick, iter)
Top-level routine that write multipoles to file, or files depending on whether a state-resolved outpu...
Definition: td_write.F90:1516
subroutine td_write_electric_field_box_surface(out_field_surf, st, dim, iter)
Definition: td_write.F90:3951
integer, parameter out_e_field_surface_y
Definition: td_write.F90:274
integer, parameter, public out_angular
Definition: td_write.F90:201
subroutine td_write_populations(out_populations, namespace, space, mesh, st, writ, dt, iter)
Definition: td_write.F90:1834
integer, parameter, public out_max
Definition: td_write.F90:201
integer, parameter out_maxwell_long_b_field
Definition: td_write.F90:274
integer, parameter, public out_energy
Definition: td_write.F90:201
integer, parameter, public out_spin
Definition: td_write.F90:201
subroutine td_write_ftchd(out_ftchd, space, mesh, st, kick, iter)
Definition: td_write.F90:1690
subroutine td_write_partial_charges(out_partial_charges, mesh, st, ions, iter)
Definition: td_write.F90:3222
integer, parameter out_dftu_max
For the Maxwell fields we increment in steps of 3 to leave room for x, y, and z output.
Definition: td_write.F90:269
subroutine td_write_laser(out_laser, space, lasers, dt, iter)
Definition: td_write.F90:2013
integer, parameter out_maxwell_total_b_field
Definition: td_write.F90:274
integer, parameter, public out_ftchd
Definition: td_write.F90:201
integer, parameter, public out_separate_velocity
Definition: td_write.F90:201
subroutine td_write_tot_mag(out_magnets, mesh, st, kick, iter)
Definition: td_write.F90:1378
subroutine td_write_q(out_q, space, ks, iter)
Definition: td_write.F90:3271
integer, parameter, public out_floquet
Definition: td_write.F90:201
integer, parameter, public out_acc
Definition: td_write.F90:201
integer, parameter, public out_ion_ch
Definition: td_write.F90:201
integer, parameter maxwell_long_field
Definition: td_write.F90:292
integer, parameter, public out_n_ex
Definition: td_write.F90:201
integer, parameter out_b_field_surface_z
Definition: td_write.F90:274
subroutine td_write_proj_kp(mesh, kpoints, st, gs_st, namespace, iter)
Definition: td_write.F90:2699
integer, parameter, public out_temperature
Definition: td_write.F90:201
subroutine td_write_norm_ks_orbitals(file_handle, grid, kpoints, st, iter)
Write the norm of the KS orbitals to file as a function of time step.
Definition: td_write.F90:3488
subroutine, public td_write_data(writ)
Definition: td_write.F90:1194
subroutine, public td_write_mxll_free_data(writ, namespace, space, gr, st, hm, helmholtz, outp, iter, time)
Definition: td_write.F90:4202
subroutine td_write_total_heat_current(write_obj, space, hm, gr, st, iter)
Definition: td_write.F90:3166
integer, parameter out_e_field_surface_z
Definition: td_write.F90:274
integer, parameter maxwell_total_field
Definition: td_write.F90:292
integer, parameter, public out_coords
Definition: td_write.F90:201
integer, parameter out_maxwell_total_e_field
Definition: td_write.F90:274
integer, parameter, public out_laser
Definition: td_write.F90:201
integer, parameter, public out_eigs
Definition: td_write.F90:201
subroutine td_write_floquet(namespace, space, hm, ext_partners, mesh, st, iter)
Definition: td_write.F90:2793
integer, parameter, public out_total_heat_current
Definition: td_write.F90:201
integer, parameter out_e_field_surface_x
Definition: td_write.F90:274
subroutine, public td_write_kick(outp, namespace, space, mesh, kick, ions, iter)
Definition: td_write.F90:334
subroutine, public td_write_end(writ)
Definition: td_write.F90:982
subroutine td_write_angular(out_angular, namespace, space, gr, ions, hm, st, kick, iter)
Computes and outputs the orbital angular momentum defined by.
Definition: td_write.F90:1445
subroutine td_write_eigs(out_eigs, st, iter)
Definition: td_write.F90:2218
subroutine, public td_write_iter(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, kick, ks, dt, iter, mc, recalculate_gs)
Definition: td_write.F90:1029
subroutine td_write_n_ex(out_nex, outp, namespace, mesh, kpoints, st, gs_st, iter)
This routine computes the total number of excited electrons based on projections on the GS orbitals T...
Definition: td_write.F90:2548
subroutine td_write_fields(out_fields, space, st, iter, dt, e_or_b_field, field_type, idir)
Definition: td_write.F90:4110
subroutine td_write_spin(out_spin, mesh, st, iter)
Definition: td_write.F90:1269
subroutine td_write_vel(out_vel, elec_me, kpoints, iter)
Definition: td_write.F90:1966
integer, parameter, public out_vel
Definition: td_write.F90:201
integer, parameter, public out_gauge_field
Definition: td_write.F90:201
subroutine td_write_temperature(out_temperature, ions, iter)
Definition: td_write.F90:1797
integer, parameter maxwell_e_field
Definition: td_write.F90:297
integer, parameter, public out_populations
Definition: td_write.F90:201
subroutine, public td_write_mxll_iter(writ, space, gr, st, hm, helmholtz, dt, iter, namespace)
Definition: td_write.F90:3760
subroutine td_write_local_magnetic_moments(out_magnets, gr, st, ions, lmm_r, iter)
Definition: td_write.F90:1321
subroutine, public td_write_init(writ, namespace, space, outp, gr, st, hm, ions, ext_partners, ks, ions_move, with_gauge_field, kick, iter, max_iter, dt, mc)
Initialize files to write when prograting in time.
Definition: td_write.F90:372
integer, parameter out_maxwell_energy
Definition: td_write.F90:274
subroutine td_write_energy(out_energy, hm, iter, ke)
Definition: td_write.F90:2135
subroutine td_write_maxwell_energy(out_maxwell_energy, hm, iter)
Definition: td_write.F90:3890
integer, parameter, public out_separate_forces
Definition: td_write.F90:201
integer, parameter out_maxwell_trans_e_field
Definition: td_write.F90:274
type(type_t), public type_cmplx
Definition: types.F90:134
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_t), public unit_kelvin
For converting energies into temperatures.
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
character pure function, public index2axis(idir)
Definition: utils.F90:202
subroutine, public v_ks_calculate_current(this, calc_cur)
Definition: v_ks.F90:1436
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:732
Explicit interfaces to C functions, defined in write_iter_low.cc.
Definition: write_iter.F90:114
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:168
Describes mesh distribution to nodes.
Definition: mesh.F90:186
This is defined even when running serial.
Definition: mpi.F90:142
Stores all communicators and groups.
Definition: multicomm.F90:206
output handler class
Definition: output_low.F90:163
The states_elec_t class contains all electronic wave functions.
Time-dependent Write Properties.
Definition: td_write.F90:315
int true(void)
subroutine dipole_matrix_elements(dir)
Definition: td_write.F90:2492