Octopus
output_me.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2023 F. Troisi
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module output_me_oct_m
23 use debug_oct_m
26 use global_oct_m
27 use grid_oct_m
30 use io_oct_m
31 use ions_oct_m
33 use mpi_oct_m
38 use parser_oct_m
41 use space_oct_m
45 use unit_oct_m
47 use utils_oct_m
49 use xc_oct_m
50
51 implicit none
52
53 private
54 public :: &
57
58contains
59
60 ! ---------------------------------------------------------
61 subroutine output_me_init(this, namespace, space, st, gr, nst)
62 type(output_me_t), intent(out) :: this
63 type(namespace_t), intent(in) :: namespace
64 class(space_t), intent(in) :: space
65 type(states_elec_t), intent(in) :: st
66 type(grid_t), intent(in) :: gr
67 integer, intent(in) :: nst
68
69 integer(int64) :: how(0:MAX_OUTPUT_TYPES)
70 integer :: output_interval(0:MAX_OUTPUT_TYPES)
71
72 push_sub(output_me_init)
73
74 !%Variable OutputMatrixElements
75 !%Type block
76 !%Default none
77 !%Section Output
78 !%Description
79 !% Specifies what matrix elements to print.
80 !% Enabled only if <tt>Output</tt> block includes <tt>matrix_elements</tt>.
81 !% The output files go into the <tt>static</tt> directory, except when
82 !% running a time-dependent simulation, when the directory <tt>td.XXXXXXX</tt> is used.
83 !%
84 !% Example:
85 !% <br><br><tt>%OutputMatrixElements
86 !% <br>&nbsp;&nbsp;momentum
87 !% <br>&nbsp;&nbsp;ks_multipoles
88 !% <br>%<br></tt>
89 !%
90 !% It is possible to specify only compute the matrix elements for some of the states
91 !% using the variables <tt>OutptMEStart</tt> and <tt>OutputMEEnd</tt>.
92 !%Option momentum 1
93 !% Momentum. Filename: <tt>ks_me_momentum</tt>.
94 !% This does not include the nonlocal part of the pseudopotential, nor any nonlocal operator.
95 !% These are included in the velocity operator.
96 !% In case of a vector potential, this returns the matrix element of the canonical momentum
97 !% <math>\hat{\boldsymbol{\Pi}} = \hat{\mathbf{p}}-\mathbf{A}</math>.
98 !%Option ang_momentum 2
99 !% Dimensionless angular momentum <math>\vec{r} \times \vec{k}</math>. Filename: <tt>ks_me_angular_momentum</tt>.
100 !%Option one_body 3
101 !% <math>\left< i \left| \hat{T} + V_{ext} \right| j \right></math>. Not available with states parallelization.
102 !%Option two_body 4
103 !% <math>\left< ij \left| \frac{1}{\left|\vec{r}_1-\vec{r}_2\right|} \right| kl \right></math>.
104 !% Not available with states parallelization.
105 !% Not available with states parallelization. For periodic system, this is not available for k-point parallelization neither.
106 !%Option two_body_exc_k 5
107 !% <math>\left< n1-k1, n2-k2 \left| \frac{1}{\left|\vec{r}_1-\vec{r}_2\right|} \right| n2-k1 n1-k2 \right></math>.
108 !% Not available with states parallelization. For periodic system, this is not available for k-point parallelization neither.
109 !%Option ks_multipoles 6
110 !% See <tt>OutputMEMultipoles</tt>. Not available with states parallelization.
111 !%Option dipole 7
112 !% Prints the dipole matrix elements. Not available with states parallelization.
113 !% For periodic systems, the intraband terms (dipole matrix elements between degenerated states)
114 !% are set to zero, and only the absolute value of the dipole matrix element is printed.
115 !% Not yet supported for spinors.
116 !%Option velocity 8
117 !% Velocity matrix elements, defined as the matrix elements of <math>\hat{v} = \hat{p}/m -i/\hbar[\hat{V}_{NL},\vec{r}]</math>.
118 !%End
119
120 this%what = .false.
121 call io_function_read_what_how_when(namespace, space, this%what, how, output_interval, &
122 'OutputMatrixElements')
123
124 if (st%parallel_in_states) then
125 if (this%what(option__outputmatrixelements__two_body)) then
126 call messages_not_implemented("OutputMatrixElements=two_body is not implemented in states parallelization.", &
127 namespace=namespace)
128 end if
129 if (this%what(option__outputmatrixelements__dipole)) then
130 call messages_not_implemented("OutputMatrixElements=dipole is not implemented in states parallelization.", &
131 namespace=namespace)
132 end if
133 end if
134
135 if (space%dim /= 3) this%what(option__outputmatrixelements__ang_momentum) = .false.
136
137 if (this%what(option__outputmatrixelements__ks_multipoles)) then
138 !%Variable OutputMEMultipoles
139 !%Type integer
140 !%Default 1
141 !%Section Output
142 !%Description
143 !% This variable decides which multipole moments are printed out for
144 !% <tt>OutputMatrixElements = ks_multipoles</tt>:
145 !%
146 !% In 3D, if, for example, <tt>OutputMEMultipoles = 1</tt>, then the program will print three
147 !% files, <tt>ks_me_multipoles.x</tt> (<tt>x</tt>=1,2,3), containing
148 !% respectively the (1,-1), (1,0) and (1,1) multipole matrix elements
149 !% between Kohn-Sham states.
150 !%
151 !% In 2D, this variable is ignored: it will always print two files,
152 !% <tt>ks_me_multipoles.i</tt> (<tt>i</tt>=1,2), containing the <math>x</math> and
153 !% <math>y</math> dipole matrix elements.
154 !%
155 !% In 1D, if, for example, <tt>OutputMEMultipoles = 2</tt>, the program will print two files, containing the
156 !% <math>x</math> and <math>x^2</math> matrix elements between Kohn-Sham states.
157 !%End
158 call parse_variable(namespace, 'OutputMEMultipoles', 1, this%ks_multipoles)
159 end if
160
161 !%Variable OutputMEStart
162 !%Type integer
163 !%Default 1
164 !%Section Output
165 !%Description
166 !% Specifies the state/band index for starting to compute the matrix element.
167 !% So far, this is only used for dipole matrix elements.
168 !%End
169 call parse_variable(namespace, 'OutputMEStart', 1, this%st_start)
170 assert(this%st_start > 0 .and. this%st_start <= nst)
171
172 !%Variable OutputMEEnd
173 !%Type integer
174 !%Default 1
175 !%Section Output
176 !%Description
177 !% Specifies the highest state/band index used to compute the matrix element.
178 !% So far, this is only used for dipole matrix elements.
179 !%End
180 call parse_variable(namespace, 'OutputMEEnd', nst, this%st_end)
181 if (this%st_end <= 0 .or. this%st_end > nst .or. this%st_start > this%st_end) then
182 message(1) = "OutputMEEnd must be positive, smaller or equal to the number of states, and larger than OutputMEStart"
183 call messages_fatal(1, namespace=namespace)
184 end if
185 this%nst = this%st_end - this%st_start +1
186
187 pop_sub(output_me_init)
188 end subroutine output_me_init
189
190
191 ! ---------------------------------------------------------
192 subroutine output_me(this, namespace, space, dir, st, gr, ions, hm)
193 type(output_me_t), intent(in) :: this
194 type(namespace_t), intent(in) :: namespace
195 class(space_t), intent(in) :: space
196 character(len=*), intent(in) :: dir
197 type(states_elec_t), intent(inout) :: st
198 type(grid_t), intent(in) :: gr
199 type(ions_t), intent(in) :: ions
200 type(hamiltonian_elec_t), intent(inout) :: hm
201
202 integer :: id, ll, iunit
203 character(len=256) :: fname
204 real(real64), allocatable :: doneint(:), dtwoint(:)
205 complex(real64), allocatable :: zoneint(:), ztwoint(:)
206 integer, allocatable :: iindex(:,:), jindex(:,:), kindex(:,:), lindex(:,:)
207 type(singularity_t) :: singul
208
209 push_sub(output_me)
210
211 if (this%what(option__outputmatrixelements__momentum)) then
212 write(fname,'(2a)') trim(dir), '/ks_me_momentum'
213 call output_me_out_momentum(gr, st, space, fname, namespace, hm, ions)
214 end if
215
216 if (this%what(option__outputmatrixelements__velocity)) then
217 write(fname,'(2a)') trim(dir), '/ks_me_velocity'
218 call output_me_out_momentum(gr, st, space, fname, namespace, hm, ions, non_local=.true.)
219 end if
220
221 if (this%what(option__outputmatrixelements__ang_momentum)) then
222 write(fname,'(2a)') trim(dir), '/ks_me_angular_momentum'
223 call output_me_out_ang_momentum(gr, st, space, fname, namespace, hm%kpoints)
224 end if
225
226 if (this%what(option__outputmatrixelements__ks_multipoles)) then
227 call output_me_out_ks_multipoles(gr, st, space, dir, this, namespace)
228 end if
229
230 if (this%what(option__outputmatrixelements__dipole)) then
231 assert(.not. st%parallel_in_states)
232 call output_me_out_dipole(gr, st, space, dir, namespace, hm, ions, this%st_start, this%st_end)
233 end if
234
235 if (this%what(option__outputmatrixelements__one_body)) then
236 message(1) = "Computing one-body matrix elements"
237 call messages_info(1, namespace=namespace)
238
239 if (st%parallel_in_states) call messages_not_implemented("OutputMatrixElements=one_body with states parallelization", &
240 namespace=namespace)
241 if (st%d%kpt%parallel) call messages_not_implemented("OutputMatrixElements=one_body with k-points parallelization", &
242 namespace=namespace)
243 if (family_is_mgga_with_exc(hm%xc)) then
244 call messages_not_implemented("OutputMatrixElements=one_body with MGGA", namespace=namespace)
245 end if
246 ! how to do this properly? states_elec_matrix
247 iunit = io_open(trim(dir)//'/output_me_one_body', namespace, action='write')
248
249 id = st%nst*(st%nst+1)/2
250
251 safe_allocate(iindex(1:id,1))
252 safe_allocate(jindex(1:id,1))
253
254 if (states_are_real(st)) then
255 safe_allocate(doneint(1:id))
256 call one_body_me(gr, st, namespace, hm, iindex(:,1), jindex(:,1), doneint)
257 if (gr%mpi_grp%is_root()) then
258 do ll = 1, id
259 write(iunit, *) iindex(ll,1), jindex(ll,1), doneint(ll)
260 end do
261 end if
262 safe_deallocate_a(doneint)
263 else
264 safe_allocate(zoneint(1:id))
265 call one_body_me(gr, st, namespace, hm, iindex(:,1), jindex(:,1), zoneint)
266 if (gr%mpi_grp%is_root()) then
267 do ll = 1, id
268 write(iunit, *) iindex(ll,1), jindex(ll,1), zoneint(ll)
269 end do
270 end if
271 safe_deallocate_a(zoneint)
272 end if
273
274 safe_deallocate_a(iindex)
275 safe_deallocate_a(jindex)
276 call io_close(iunit)
277 end if
278
279 if (this%what(option__outputmatrixelements__two_body) .or. this%what(option__outputmatrixelements__two_body_exc_k)) then
280 message(1) = "Computing two-body matrix elements"
281 call messages_info(1, namespace=namespace)
282
283 assert(.not. st%parallel_in_states)
284 ! two_body_me needs the exchange Poisson solver in double precision
285 if (hm%exxop%compute_single_precision) then
286 call messages_not_implemented("OutputMatrixElements=two_body with ExchangeSinglePrecision", namespace=namespace)
287 end if
288 if (this%what(option__outputmatrixelements__two_body)) then
289 if (st%parallel_in_states) then
290 call messages_not_implemented("OutputMatrixElements=two_body with states parallelization", namespace=namespace)
291 end if
292 if (st%d%kpt%parallel) then
293 call messages_not_implemented("OutputMatrixElements=two_body with k-points parallelization", namespace=namespace)
294 end if
295 ! how to do this properly? states_matrix
296 iunit = io_open(trim(dir)//'/output_me_two_body', namespace, action='write')
297 if (gr%mpi_grp%is_root()) then
298 write(iunit, '(a)') '# (n1, k1) (n2, k2) (n3, k3) (n4, k4) (n1-k1, n2-k2|n3-k3, n4-k4)'
299 end if
300 else
301 if (st%parallel_in_states) then
302 call messages_not_implemented("OutputMatrixElements=two_body_exc_k with states parallelization", namespace=namespace)
303 end if
304 if (st%d%kpt%parallel) then
305 call messages_not_implemented("OutputMatrixElements=two_body_exc_k with k-points parallelization", namespace=namespace)
306 end if
307 ! how to do this properly? states_matrix
308 iunit = io_open(trim(dir)//'/output_me_two_body_density', namespace, action='write')
309 if (gr%mpi_grp%is_root()) then
310 write(iunit, '(a)') '#(n1, k1) (n2, k2) (n1-k1, n1-k2|n2-k2, n2-k1)'
311 end if
312 end if
313
314 if (this%what(option__outputmatrixelements__two_body)) then
315 if (states_are_real(st)) then
316 id = st%nik*this%nst*(st%nik*this%nst+1)*(st%nik**2*this%nst**2+st%nik*this%nst+2)/8
317 else
318 id = (st%nik*this%nst)**4
319 end if
320 else
321 id = (st%nik*this%nst)**2
322 end if
323
324 if (states_are_complex(st)) then
325 call singularity_init(singul, namespace, space, st, hm%kpoints)
326 end if
327
328 safe_allocate(iindex(1:2, 1:id))
329 safe_allocate(jindex(1:2, 1:id))
330 safe_allocate(kindex(1:2, 1:id))
331 safe_allocate(lindex(1:2, 1:id))
332
333 if (states_are_real(st)) then
334 safe_allocate(dtwoint(1:id))
335 call two_body_me(gr, st, space, namespace, hm%kpoints, hm%exxop%psolver, this%st_start, this%st_end, &
336 iindex, jindex, kindex, lindex, dtwoint)
337 if (gr%mpi_grp%is_root()) then
338 do ll = 1, id
339 write(iunit, '(4(i4,i5,1x),es22.12)') iindex(1:2,ll), jindex(1:2,ll), kindex(1:2,ll), lindex(1:2,ll), dtwoint(ll)
340 end do
341 end if
342 safe_deallocate_a(dtwoint)
343 else
344 safe_allocate(ztwoint(1:id))
345 if (hm%phase%is_allocated()) then
346 !We cannot pass the phase array like that if kpt%start is not 1.
347 assert(.not. st%d%kpt%parallel)
348 call two_body_me(gr, st, space, namespace, hm%kpoints, hm%exxop%psolver, this%st_start, this%st_end, iindex, jindex, &
349 kindex, lindex, ztwoint, phase = hm%phase, singularity = singul, &
350 exc_k = (this%what(option__outputmatrixelements__two_body_exc_k)))
351 else
352 call two_body_me(gr, st, space, namespace, hm%kpoints, hm%exxop%psolver, this%st_start, this%st_end, &
353 iindex, jindex, kindex, lindex, ztwoint, exc_k = (this%what(option__outputmatrixelements__two_body_exc_k)))
354 end if
355
356 if (gr%mpi_grp%is_root()) then
357 if (this%what(option__outputmatrixelements__two_body)) then
358 do ll = 1, id
359 write(iunit, '(4(i4,i5,1x),2es22.12)') iindex(1:2,ll), jindex(1:2,ll), kindex(1:2,ll), lindex(1:2,ll), ztwoint(ll)
360 end do
361 else
362 do ll = 1, id
363 write(iunit, '(2(i4,i5),2es22.12)') iindex(1:2,ll), kindex(1:2,ll), ztwoint(ll)
364 end do
365 end if
366 end if
367 safe_deallocate_a(ztwoint)
368 end if
369
370 safe_deallocate_a(iindex)
371 safe_deallocate_a(jindex)
372 safe_deallocate_a(kindex)
373 safe_deallocate_a(lindex)
374 call io_close(iunit)
375
376 if (states_are_complex(st)) then
377 call singularity_end(singul)
378 end if
379 end if
380
381 pop_sub(output_me)
382 end subroutine output_me
383
384
385 ! ---------------------------------------------------------
386 subroutine output_me_out_momentum(gr, st, space, fname, namespace, hm, ions, non_local)
387 type(grid_t), intent(in) :: gr
388 type(states_elec_t), intent(in) :: st
389 type(space_t), intent(in) :: space
390 character(len=*), intent(in) :: fname
391 type(namespace_t), intent(in) :: namespace
392 type(hamiltonian_elec_t), intent(in) :: hm
393 type(ions_t), intent(in) :: ions
394 logical, optional, intent(in) :: non_local
395
396 integer :: ik, ist, is, ns, iunit, idir, dim
397 character(len=80) :: cspin, str_tmp
398 real(real64) :: kpoint(space%dim)
399 real(real64), allocatable :: momentum(:,:,:)
400
401 push_sub(output_me_out_momentum)
402
403 dim = space%dim
404
405 safe_allocate(momentum(1:dim, 1:st%nst, 1:st%nik))
406
407 ! Compute matrix elements
408 call elec_momentum_me(namespace, gr, st, space, hm, ions, momentum, non_local)
409
410 iunit = io_open(fname, namespace, action='write')
411
412 ns = 1
413 if (st%d%nspin == 2) ns = 2
414
415 if (optional_default(non_local, .false.)) then
416 write(message(1),'(a)') 'Velocity of the KS states [a.u.]:'
417 else
418 write(message(1),'(a)') 'Momentum of the KS states [a.u.]:'
419 end if
420 call messages_info(1, iunit)
421 if (st%nik > ns) then
422 message(1) = 'k-points [' // trim(units_abbrev(unit_one/units_out%length)) // ']'
423 call messages_info(1, iunit)
424 end if
425
426 do ik = 1, st%nik, ns
427 kpoint(:) = hm%kpoints%get_point(st%d%get_kpoint_index(ik))
428
429 if (st%nik > ns) then
430 write(message(1), '(a,i4, a)') '#k =', ik, ', k = ('
431 do idir = 1, dim
432 write(str_tmp, '(f12.6)') units_from_atomic(unit_one/units_out%length, kpoint(idir))
433 message(1) = trim(message(1)) // trim(str_tmp)
434 if (idir == dim) then
435 message(1) = trim(message(1)) // ")"
436 else
437 message(1) = trim(message(1)) // ","
438 end if
439 end do
440 call messages_info(1, iunit)
441 end if
442
443 write(message(1), '(a4,1x,a5)') '#st',' Spin'
444 do idir = 1, dim
445 if (optional_default(non_local, .false.)) then
446 write(str_tmp, '(a,a1,a)') ' <v', index2axis(idir), '>'
447 else
448 write(str_tmp, '(a,a1,a)') ' <p', index2axis(idir), '>'
449 end if
450 message(1) = trim(message(1)) // trim(str_tmp)
451 end do
452 write(str_tmp, '(4x,a12,1x)') 'Occupation '
453 message(1) = trim(message(1)) // trim(str_tmp)
454 call messages_info(1, iunit)
455
456 do ist = 1, st%nst
457 do is = 0, ns-1
458
459 if (is == 0) cspin = 'up'
460 if (is == 1) cspin = 'dn'
461 if (st%d%ispin == unpolarized .or. st%d%ispin == spinors) cspin = '--'
462
463 write(message(1), '(i4,3x,a2,1x)') ist, trim(cspin)
464 do idir = 1, dim
465 write(str_tmp, '(f12.6)') momentum(idir, ist, ik+is)
466 message(1) = trim(message(1)) // trim(str_tmp)
467 end do
468 write(str_tmp, '(3x,f12.6)') st%occ(ist, ik+is)
469 message(1) = trim(message(1)) // trim(str_tmp)
470 call messages_info(1, iunit)
471
472 end do
473 end do
474
475 write(message(1),'(a)') ''
476 call messages_info(1, iunit)
477
478 end do
479
480 safe_deallocate_a(momentum)
481 call io_close(iunit)
482
484 end subroutine output_me_out_momentum
485
486
487 ! ---------------------------------------------------------
488 subroutine output_me_out_ang_momentum(gr, st, space, fname, namespace, kpoints)
489 type(grid_t), intent(in) :: gr
490 type(states_elec_t), intent(in) :: st
491 type(space_t), intent(in) :: space
492 character(len=*), intent(in) :: fname
493 type(namespace_t), intent(in) :: namespace
494 type(kpoints_t), intent(in) :: kpoints
495
496 integer :: iunit, ik, ist, is, ns, idir, k_start, k_end, k_n, dim, st_start, st_end, nst
497 character(len=80) :: tmp_str(space%dim), cspin
498 real(real64) :: angular(3), lsquare, kpoint(space%dim)
499 real(real64), allocatable :: ang(:, :, :), ang2(:, :)
500#if defined(HAVE_MPI)
501 integer :: tmp
502#endif
503 real(real64), allocatable :: lang(:, :)
504
506
507 ns = 1
508 if (st%d%nspin == 2) ns = 2
509 assert(space%dim == 3)
510 ! Define useful quantities
511 dim = space%dim ! Space dimension
512 st_start = st%st_start ! Starting state
513 st_end = st%st_end ! Last state
514 nst = st%nst ! Number of states
515
516 iunit = io_open(fname, namespace, action='write')
517
518 if (st%system_grp%is_root()) then
519 write(iunit,'(a)') 'Warning: When non-local pseudopotentials are used '
520 write(iunit,'(a)') ' the numbers below may be meaningless. '
521 write(iunit,'(a)') ' '
522 write(iunit,'(a)') 'Angular Momentum of the KS states [dimensionless]:'
523 ! r x k is dimensionless. we do not include hbar.
524 if (st%nik > ns) then
525 message(1) = 'k-points [' // trim(units_abbrev(unit_one/units_out%length)) // ']'
526 call messages_info(1, iunit)
527 end if
528 end if
529
530 safe_allocate(ang(1:nst, 1:st%nik, 1:3))
531 safe_allocate(ang2(1:nst, 1:st%nik))
532
533 ! Compute matrix elements
534 call elec_angular_momentum_me(gr, st, space, ang, ang2)
535
536 k_start = st%d%kpt%start
537 k_end = st%d%kpt%end
538 do idir = 1, 3
539 angular(idir) = states_elec_eigenvalues_sum(st, ang(st_start:st_end, k_start:k_end, idir))
540 end do
541 lsquare = states_elec_eigenvalues_sum(st, ang2(st_start:st_end, k_start:k_end))
542
543 if (st%d%kpt%parallel) then
544 k_n = st%d%kpt%nlocal()
545
546 assert(.not. st%parallel_in_states)
547
548 ! note: could use lmpi_gen_allgatherv here?
549 safe_allocate(lang(1:st%lnst, 1:k_n))
550 do idir = 1, 3
551 lang(1:st%lnst, 1:k_n) = ang(st_start:st_end, k_start:k_end, idir)
552 call st%d%kpt%mpi_grp%allgatherv(lang, nst*k_n, mpi_double_precision, ang(:, :, idir), &
553 st%d%kpt%num(:)*nst, (st%d%kpt%range(1, :) - 1)*nst, mpi_double_precision)
554 end do
555 lang(1:st%lnst, 1:k_n) = ang2(st_start:st_end, k_start:k_end)
556 call st%d%kpt%mpi_grp%allgatherv(lang, nst*k_n, mpi_double_precision, ang2, &
557 st%d%kpt%num(:)*nst, (st%d%kpt%range(1, :) - 1)*nst, mpi_double_precision)
558 safe_deallocate_a(lang)
559 end if
560
561 if (st%parallel_in_states) then
562 safe_allocate(lang(1:st%lnst, 1))
563 end if
564
565 do ik = 1, st%nik, ns
566 if (st%nik > ns) then
567
568 kpoint(:) = kpoints%get_point(st%d%get_kpoint_index(ik))
569
570 write(message(1), '(a,i4, a)') '#k =', ik, ', k = ('
571 do idir = 1, dim
572 write(tmp_str(1), '(f12.6, a)') units_from_atomic(unit_one/units_out%length, kpoint(idir)), ','
573 message(1) = trim(message(1)) // trim(tmp_str(1))
574 if (idir == dim) then
575 message(1) = trim(message(1)) // ")"
576 else
577 message(1) = trim(message(1)) // ","
578 end if
579 end do
580 call messages_info(1, iunit)
581 end if
582
583 ! Exchange ang and ang2.
584 if (st%parallel_in_states) then
585 assert(.not. st%d%kpt%parallel)
586#if defined(HAVE_MPI)
587 do is = 1, ns
588 do idir = 1, 3
589 lang(1:st%lnst, 1) = ang(st_start:st_end, ik+is-1, idir)
590 call lmpi_gen_allgatherv(st%lnst, lang(:, 1), tmp, ang(:, ik+is-1, idir), st%mpi_grp)
591 end do
592 lang(1:st%lnst, 1) = ang2(st_start:st_end, ik+is-1)
593 call lmpi_gen_allgatherv(st%lnst, lang(:, 1), tmp, ang2(:, ik+is-1), st%mpi_grp)
594 end do
595#endif
596 end if
597
598 write(message(1), '(a4,1x,a5,4a12,4x,a12,1x)') &
599 '#st',' Spin',' <Lx>', ' <Ly>', ' <Lz>', ' <L2>', 'Occupation '
600 call messages_info(1, iunit)
601
602 if (st%system_grp%is_root()) then
603 do ist = 1, nst
604 do is = 0, ns-1
605
606 if (is == 0) cspin = 'up'
607 if (is == 1) cspin = 'dn'
608 if (st%d%ispin == unpolarized .or. st%d%ispin == spinors) cspin = '--'
609
610 write(tmp_str(1), '(i4,3x,a2)') ist, trim(cspin)
611 write(tmp_str(2), '(1x,4f12.6,3x,f12.6)') &
612 (ang(ist, ik+is, idir), idir = 1, 3), ang2(ist, ik+is), st%occ(ist, ik+is)
613 message(1) = trim(tmp_str(1))//trim(tmp_str(2))
614 call messages_info(1, iunit)
615 end do
616 end do
617 end if
618 write(message(1),'(a)') ''
619 call messages_info(1, iunit)
620
621 end do
622
623 write(message(1),'(a)') 'Total Angular Momentum L [dimensionless]'
624 write(message(2),'(10x,4f12.6)') angular(1:3), lsquare
625 call messages_info(2, iunit)
626
627 call io_close(iunit)
628
629 if (st%parallel_in_states) then
630 safe_deallocate_a(lang)
631 end if
632
633 safe_deallocate_a(ang)
634 safe_deallocate_a(ang2)
635
637 end subroutine output_me_out_ang_momentum
638
639 subroutine output_me_out_dipole(gr, st, space, dir, namespace, hm, ions, st_start, st_end)
640 type(grid_t), intent(in) :: gr
641 type(states_elec_t), intent(in) :: st
642 type(space_t), intent(in) :: space
643 character(len=*), intent(in) :: dir
644 type(namespace_t), intent(in) :: namespace
645 type(hamiltonian_elec_t), intent(in) :: hm
646 type(ions_t), intent(in) :: ions
647 integer, intent(in) :: st_start, st_end
648
649 integer :: ik, idir, ist, jst, iunit
650 character(len=256) :: fname
651 real(real64), allocatable :: ddip_elements(:,:,:)
652 complex(real64), allocatable :: zdip_elements(:,:,:)
653
654 push_sub(output_me_out_dipole)
655
656 ! The content of each file should be clear from the header of each file.
657 do ik = st%d%kpt%start, st%d%kpt%end
658 write(fname,'(i8)') ik
659 write(fname,'(a)') trim(dir)//'/ks_me_dipole.k'//trim(adjustl(fname))//'_'
660
661 if (states_are_real(st)) then
662 ! Allocate dipole array
663 safe_allocate(ddip_elements(1:space%dim, st_start:st_end, st_start:st_end))
664 ! Compute dipole elements
665 call dipole_me(gr, st, namespace, hm, ions, ik, st_start, st_end, ddip_elements)
666 ! Output elements
667 do idir = 1, space%dim
668 iunit = io_open(trim(fname)//index2axis(idir), namespace, action = 'write')
669 write(iunit, '(a)') '# Dipole matrix elements file: |<Phi_i | r | Phi_j>|'
670 write(iunit, '(a,i8)') '# ik =', ik
671 write(iunit, '(a)') '# Units = ['//trim(units_abbrev(units_out%length))//']'
672
673 do ist = st_start, st_end
674 do jst = st_start, st_end
675 write(iunit, fmt='(f20.12)', advance = 'no') units_from_atomic(units_out%length, abs(ddip_elements(idir, ist, jst)))
676 write(iunit, fmt='(a)', advance = 'no') ' '
677 end do
678 write(iunit, '(a)') '' ! New line
679 end do
680 call io_close(iunit)
681 end do
682 safe_deallocate_a(ddip_elements)
683 else
684 ! Allocate dipole array
685 safe_allocate(zdip_elements(1:space%dim, st_start:st_end, st_start:st_end))
686 ! Compute dipole elements
687 call dipole_me(gr, st, namespace, hm, ions, ik, st_start, st_end, zdip_elements)
688 ! Output elements
689 do idir = 1, space%dim
690 iunit = io_open(trim(fname)//index2axis(idir), namespace, action = 'write')
691 write(iunit, '(a)') '# Dipole matrix elements file: |<Phi_i | r | Phi_j>|'
692 write(iunit, '(a,i8)') '# ik =', ik
693 write(iunit, '(a)') '# Units = ['//trim(units_abbrev(units_out%length))//']'
694
695 do ist = st_start, st_end
696 do jst = st_start, st_end
697 write(iunit, fmt='(f20.12)', advance = 'no') units_from_atomic(units_out%length, abs(zdip_elements(idir, ist, jst)))
698 write(iunit, fmt='(a)', advance = 'no') ' '
699 end do
700 write(iunit, '(a)') '' ! New line
701 end do
702 call io_close(iunit)
703 end do
704 safe_deallocate_a(zdip_elements)
705 end if
706 end do
707
708 pop_sub(output_me_out_dipole)
709 end subroutine output_me_out_dipole
710
711 subroutine output_me_out_ks_multipoles(gr, st, space, dir, this, namespace)
712 type(grid_t), intent(in) :: gr
713 type(states_elec_t), intent(in) :: st
714 type(space_t), intent(in) :: space
715 character(len=*), intent(in) :: dir
716 type(output_me_t), intent(in) :: this
717 type(namespace_t), intent(in) :: namespace
718
719 integer :: id, ll, mm, ik, iunit
720 character(len=256) :: fname
721 real(real64), allocatable :: delements(:,:)
722 complex(real64), allocatable :: zelements(:,:)
723
726 ! The content of each file should be clear from the header of each file.
727 id = 1
728 mm = 0
729 do ik = 1, st%nik
730 select case (space%dim)
731 case (3)
732 do ll = 1, this%ks_multipoles
733 do mm = -ll, ll
734 ! Define file name
735 write(fname,'(i4)') id
736 write(fname,'(a)') trim(dir) // '/ks_me_multipoles.' // trim(adjustl(fname))
737 iunit = io_open(fname, namespace, action = 'write')
738 ! Print header
739 call print_ks_multipole_header(iunit, ll, mm, ik)
740 ! Compute and print elements
741 if (states_are_real(st)) then
742 safe_allocate(delements(1:st%nst, 1:st%nst))
743 call ks_multipoles_3d(gr, st, space, ll, mm, ik, delements)
744 call dprint_ks_multipole(iunit, st%nst, delements, ll)
745 safe_deallocate_a(delements)
746 else
747 safe_allocate(zelements(1:st%nst, 1:st%nst))
748 call ks_multipoles_3d(gr, st, space, ll, mm, ik, zelements)
749 call zprint_ks_multipole(iunit, st%nst, zelements, ll)
750 safe_deallocate_a(zelements)
751 end if
752 ! Close file
753 call io_close(iunit)
754 id = id + 1
755 end do
756 end do
757 case (2)
758 do ll = 1, 2
759 mm = 0
760 ! Define file name
761 write(fname,'(i4)') id
762 write(fname,'(a)') trim(dir) // '/ks_me_multipoles.' // trim(adjustl(fname))
763 iunit = io_open(fname, namespace, action = 'write')
764 ! Print header
765 call print_ks_multipole_header(iunit, ll, mm, ik)
766 ! Compute and print elements
767 if (states_are_real(st)) then
768 safe_allocate(delements(1:st%nst, 1:st%nst))
769 call ks_multipoles_2d(gr, st, ll, ik, delements)
770 call dprint_ks_multipole(iunit, st%nst, delements)
771 safe_deallocate_a(delements)
772 else
773 safe_allocate(zelements(1:st%nst, 1:st%nst))
774 call ks_multipoles_2d(gr, st, ll, ik, zelements)
775 call zprint_ks_multipole(iunit, st%nst, zelements)
776 safe_deallocate_a(zelements)
777 end if
778 ! Close file
779 call io_close(iunit)
780 id = id + 1
781 end do
782 case (1)
783 do ll = 1, this%ks_multipoles
784 mm = 0
785 ! Define file name
786 write(fname,'(i4)') id
787 write(fname,'(a)') trim(dir) // '/ks_me_multipoles.' // trim(adjustl(fname))
788 iunit = io_open(fname, namespace, action = 'write')
789 ! Print header
790 call print_ks_multipole_header(iunit, ll, mm, ik)
791 ! Compute and print elements
792 if (states_are_real(st)) then
793 safe_allocate(delements(1:st%nst, 1:st%nst))
794 call ks_multipoles_1d(gr, st, ll, ik, delements)
795 call dprint_ks_multipole(iunit, st%nst, delements, ll)
796 safe_deallocate_a(delements)
797 else
798 safe_allocate(zelements(1:st%nst, 1:st%nst))
799 call ks_multipoles_1d(gr, st, ll, ik, zelements)
800 call zprint_ks_multipole(iunit, st%nst, zelements, ll)
801 safe_deallocate_a(zelements)
802 end if
803 ! Close file
804 call io_close(iunit)
805 id = id + 1
806 end do
807 end select
808 end do
809
811
812 contains
813
814 subroutine print_ks_multipole_header(iunit, ll, mm, ik)
815 integer, intent(in) :: iunit, ll, mm, ik
816
817 write(iunit, fmt = '(a)') '# Multipole matrix elements file: <Phi_i | r**l * Y_{lm}(theta,phi) | Phi_j>'
818 write(iunit, fmt = '(a,i2,a,i2)') '# l =', ll, '; m =', mm
819 write(iunit, fmt = '(a,i8)') '# ik =', ik
820 if (ll>1) then
821 write(iunit, fmt = '(a,i1)') '# Units = ['//trim(units_abbrev(units_out%length))//']^', ll
822 else
823 write(iunit, fmt = '(a)') '# Units = ['//trim(units_abbrev(units_out%length))//']'
824 end if
825 end subroutine print_ks_multipole_header
826
827 subroutine dprint_ks_multipole(iunit, nst, elements, ll)
828 integer, intent(in) :: iunit, nst
829 real(real64), contiguous, intent(in) :: elements(:,:)
830 integer, optional, intent(in) :: ll
831
832 integer :: ist, jst
833 real(real64) :: element
834
835 do ist = 1, nst
836 do jst = 1, nst
837 element = units_from_atomic(units_out%length**optional_default(ll, 1), elements(ist, jst))
838 write(iunit, fmt='(f20.12, a)', advance = 'no') element, ' '
839 end do
840 write(iunit, '(a)') ''
841 end do
842 end subroutine dprint_ks_multipole
843
844 subroutine zprint_ks_multipole(iunit, nst, elements, ll)
845 integer, intent(in) :: iunit, nst
846 complex(real64), contiguous, intent(in) :: elements(:,:)
847 integer, optional, intent(in) :: ll
848
849 integer :: ist, jst
850 complex(real64) :: element
851
852 do ist = 1, nst
853 do jst = 1, nst
854 element = units_from_atomic(units_out%length**optional_default(ll, 1), elements(ist, jst))
855 write(iunit, fmt='(f20.12,a1,f20.12,a)', advance = 'no') real(element),',',aimag(element), ' '
856 end do
857 write(iunit, '(a)') ''
858 end do
859 end subroutine zprint_ks_multipole
860
861 end subroutine output_me_out_ks_multipoles
862
863
864#include "undef.F90"
865#include "real.F90"
866
867#include "undef.F90"
868#include "complex.F90"
869
870end module output_me_oct_m
871
872!! Local Variables:
873!! mode: f90
874!! coding: utf-8
875!! End:
subroutine, public elec_angular_momentum_me(gr, st, space, ll, l2)
subroutine, public elec_momentum_me(namespace, gr, st, space, hm, ions, momentum, non_local)
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
This module implements the underlying real-space grid.
Definition: grid.F90:119
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:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module contains some common usage patterns of MPI routines.
Definition: mpi_lib.F90:117
this module contains the low-level part of the output system
Definition: output_low.F90:117
subroutine output_me_out_ang_momentum(gr, st, space, fname, namespace, kpoints)
Definition: output_me.F90:584
subroutine output_me_out_dipole(gr, st, space, dir, namespace, hm, ions, st_start, st_end)
Definition: output_me.F90:726
subroutine, public output_me_init(this, namespace, space, st, gr, nst)
Definition: output_me.F90:157
subroutine, public output_me(this, namespace, space, dir, st, gr, ions, hm)
Definition: output_me.F90:288
subroutine output_me_out_ks_multipoles(gr, st, space, dir, this, namespace)
Definition: output_me.F90:798
subroutine output_me_out_momentum(gr, st, space, fname, namespace, hm, ions, non_local)
Definition: output_me.F90:482
subroutine, public singularity_end(this)
subroutine, public singularity_init(this, namespace, space, st, kpoints)
pure logical function, public states_are_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
real(real64) function, public states_elec_eigenvalues_sum(st, alt_eig)
function to calculate the eigenvalues sum using occupations as weights
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_t), public unit_one
some special units required for particular quantities
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:120
character pure function, public index2axis(idir)
Definition: utils.F90:211
Definition: xc.F90:120
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
Definition: xc.F90:736
subroutine print_ks_multipole_header(iunit, ll, mm, ik)
Definition: output_me.F90:901
subroutine zprint_ks_multipole(iunit, nst, elements, ll)
Definition: output_me.F90:931
subroutine dprint_ks_multipole(iunit, nst, elements, ll)
Definition: output_me.F90:914
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Output information for matrix elements.
Definition: output_low.F90:133
The states_elec_t class contains all electronic wave functions.
int true(void)