Octopus
photoelectron_spectrum.F90
Go to the documentation of this file.
1!! Copyright (C) 2011 U. De Giovannini
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
27 use debug_oct_m
29 use global_oct_m
32 use io_oct_m
33 use ions_oct_m
37 use parser_oct_m
43 use sort_oct_m
44 use space_oct_m
45 use string_oct_m
48 use unit_oct_m
50 use utils_oct_m
51 use mpi_oct_m
52
53 implicit none
54
55 type pesoutput_t
56 logical :: what(MAX_OUTPUT_TYPES)
57 integer(int64) :: how(0:MAX_OUTPUT_TYPES)
58 integer :: output_interval(0:MAX_OUTPUT_TYPES)
59 real(real64) :: pol(3)
60 real(real64) :: pvec(3)
61 end type pesoutput_t
62
63 integer :: ierr, integrate
64 integer :: dim, dir, idim, pdim
65 logical :: what(MAX_OUTPUT_TYPES)
66 integer :: llp(3), llpp(3)
67 real(real64) :: Emax, Emin, Estep, uEstep,uEspan(2), pol(3)
68 real(real64) :: uThstep, uThspan(2), uPhstep, uPhspan(2), pvec(3)
69 real(real64) :: center(3)
70 real(real64), allocatable :: Lg(:,:), RR(:)
71 real(real64), allocatable :: pmesh(:,:,:,:)
72 integer, allocatable :: Lp(:,:,:,:,:)
73 logical :: need_pmesh, resolve_states
74 integer :: ii, i1,i2,i3, idxZero(1:3), st_range(2)
75 type(block_t) :: blk
76
77 type(electron_space_t) :: space
78 type(ions_t), pointer :: ions
79 type(states_elec_t) :: st
80 type(kpoints_t) :: kpoints
81 type(restart_t) :: restart
82
83 character(len=512) :: filename
84
85 logical :: have_zweight_path, use_zweight_path
86 integer :: krng(2), nkpt, kpth_dir
87
88 type(pesoutput_t) :: pesout
89
90 integer :: ist, ispin
91 real(real64), pointer :: pesP_out(:,:,:)
92 real(real64), allocatable, target :: pesP(:,:,:,:)
93 real(real64), allocatable :: Ekin(:,:,:)
94
95 type(pes_flux_t) :: pflux
96 integer :: pes_method, option
97
98 type(calc_mode_par_t) :: calc_mode
99 type(multicomm_t) :: mc
100 integer(int64) :: index_range(4)
101 integer :: nspin
102
103 class(coordinate_system_t), pointer :: coord_system
104
105 call getopt_init(ierr)
106 if (ierr /= 0) then
107 message(1) = "Your Fortran compiler doesn't support command-line arguments;"
108 message(2) = "the oct-photoelectron-spectrum command is not available."
109 call messages_fatal(2)
110 end if
111
113
114 call parser_init()
115
117 call io_init()
119
120 !* In order to initialize k-points
122
125
126 ! we need k-points for periodic systems
127 call kpoints_init(kpoints, global_namespace, ions%symm, space%dim, space%periodic_dim, ions%latt)
128 call states_elec_init(st, global_namespace, space, ions%val_charge(), kpoints)
129 !*
130
131 !Initialize variables
132 llp(:) = 1
133 llpp(:) = 1
134
135 ! Only the pes_mask branch below assigns these; they must not be left
136 ! uninitialized as they are compared against user values for all methods
137 estep = m_zero
138 emin = m_zero
139 emax = m_zero
140
141 need_pmesh = .false.
142 dim = space%dim ! The dimensionality dim = [1,2,3]
143 pdim = space%periodic_dim
144
145 call messages_print_with_emphasis(msg="Postprocessing", namespace=global_namespace)
146
147 !Figure out which method has been used to calculate the photoelectron data
148 call parse_variable(global_namespace, 'PhotoElectronSpectrum', option__photoelectronspectrum__none, pes_method)
149
150 select case (pes_method)
151 case (option__photoelectronspectrum__pes_mask)
152 call messages_write('Will process mask-method data.')
155 ! Note that Lg(:,:) is allocated inside pes_mask_read_info
156 call pes_mask_read_info("td.general/", global_namespace, dim, emax, estep, llp(:), lg, rr)
157 ! Keep a copy the original dimensions vector
158 llpp(1:dim) = llp(1:dim)
159
160 call messages_write('Read PES_MASK info file.')
161 call messages_info()
162
163 need_pmesh = space%is_periodic()
164
165
166 case (option__photoelectronspectrum__pes_flux)
167 call messages_write('Will process flux-method data.')
168 call messages_new_line()
169 call messages_info()
170
171 option = option__pes_flux_shape__sph
172 if (dim <= 2) option = option__pes_flux_shape__cub
173 if (space%is_periodic()) option = option__pes_flux_shape__pln
174
175 call parse_variable(global_namespace, 'PES_Flux_Shape', option, pflux%surf_shape)
176 call pes_flux_reciprocal_mesh_gen(pflux, global_namespace, space, st, kpoints, mpi_comm_null, post = .true.)
177
178 llpp(1:dim) = pflux%ll(1:dim)
179 need_pmesh = .true.
180
181
182 case (option__photoelectronspectrum__pes_spm)
183 call messages_not_implemented('Postprocessing SPM data')
184 call messages_fatal()
185
186 case default
187 call messages_write('Could not find any photoelectron data')
188 call messages_fatal()
189
190 end select
191
192
193 !set default values
194
195
196 integrate = integrate_none
197 uestep = -1
198 uespan = (/-1,-1/)
199 uthstep = -1
200 uthspan = (/-1,-1/)
201 uphstep = -1
202 uphspan = (/-1,-1/)
203 center = (/0,0,0/)
204 pvec = (/1,0,0/)
205
206 what(option__photoelectronspectrumoutput__energy_tot) = .true.
207 pesout%pvec = pvec
208
209 have_zweight_path = kpoints%have_zero_weight_path()
210 use_zweight_path = have_zweight_path
211
212 call get_laser_polarization(pol)
213 ! if there is no laser set pol along the z-axis
214 if (sum(pol(1:3)**2) <= m_epsilon) pol = (/0,0,1/)
215
216 ! more defaults
217 if (space%is_periodic()) then
218 what(:) = .false.
219
220 if (dim == 2) then
221 ! write the velocity map on plane pz=0 as it contains all the informations
222 pol = (/0,1,0/)
223 pvec = (/0,0,1/)
224
225 what(option__photoelectronspectrumoutput__velocity_map_cut) = .true.
226 pesout%pol = (/0,1,0/)
227 pesout%pvec = (/0,0,1/)
228 end if
229
230 if (dim == 3) then
231 ! write the full ARPES in vtk format (this could be a big file)
232 pol = (/0,0,1/)
233
234 what(option__photoelectronspectrumoutput__arpes) = .true.
235 pesout%pol = (/0,0,1/)
236 end if
237
238 if (have_zweight_path) then
239 ! In this case the output is well defined only on a path in reciprocal space
240 ! so we are going to have only a 2D slice regardless of dim=2 or 3
241 pol = (/0,0,1/)
242 pvec = (/0,1,0/)
243
244 what(:) = .false.
245 what(option__photoelectronspectrumoutput__arpes_cut) = .true.
246 pesout%pol = (/0,0,1/)
247 pesout%pvec = (/0,1,0/)
248 end if
249
250 end if
251
252
253 ! Intialize mc
254 call calc_mode%unset_parallelization(p_strategy_domains)
255 call multicomm_init(mc, global_namespace, mpi_world, calc_mode, &
256 mpi_world%size, index_range, (/ 5000, 1, 1, 1 /))
257 index_range(:) = 100000
258
259
260 call restart%init(global_namespace, restart_td, restart_type_load, mc, ierr)
261 if (ierr /= 0) then
262 message(1) = "Unable to read time-dependent restart information."
263 call messages_fatal(1)
264 end if
265
266 !%Variable PhotoelectronSpectrumOutput
267 !%Type block
268 !%Default none
269 !%Section Utilities::oct-photoelectron_spectrum
270 !%Description
271 !% Specifies what to output extracting the photoelectron cross-section informations.
272 !% When we use polar coordinates the zenith axis is set by vec (default is the first
273 !% laser field polarization vector), theta is the inclination angle measured from
274 !% vec (from 0 to \pi), and phi is the azimuthal angle on a plane perpendicular to
275 !% vec (from 0 to 2\pi).
276 !% Each option must be in a separate row. Optionally individual output formats can be defined
277 !% for each row or they can be read separately from <tt>OutputFormat</tt> variable
278 !% in the input file.
279 !%
280 !% Example (minimal):
281 !% <br><br><tt>%PhotoelectronSpectrumOutput
282 !% <br>&nbsp;&nbsp;energy_tot
283 !% <br>&nbsp;&nbsp;velocity_map
284 !% <br>%<br></tt>
285 !%
286 !% Example (with OutputFormat):
287 !% <br><br><tt>%PhotoelectronSpectrumOutput
288 !% <br>&nbsp;&nbsp;arpes | vtk
289 !% <br>&nbsp;&nbsp;velocity_map | ncdf
290 !% <br>%<br></tt>
291 !%
292 !%Option energy_tot 1
293 !% Output the energy-resolved photoelectron spectrum: E.
294 !%Option energy_angle 2
295 !% Output the energy and angle resolved spectrum: (theta, E)
296 !% The result is integrated over phi.
297 !%Option velocity_map_cut 3
298 !% Velocity map on a plane orthogonal to pvec: (px, py). The allowed cutting planes
299 !% (pvec) can only be parallel to the x,y,z=0 planes.
300 !% Space is oriented so that the z-axis is along vec. Supports the -I option.
301 !%Option energy_xy 4
302 !% Angle and energy-resolved spectrum on the inclination plane: (Ex, Ey).
303 !% The result is integrated over ph;
304 !%Option energy_th_ph 5
305 !% Ionization probability integrated on spherical cuts: (theta, phi).
306 !%Option velocity_map 6
307 !% Full momentum-resolved ionization probability: (px, py, pz).
308 !% The output format can be controlled with <tt>OutputHow</tt> and can be vtk, ncdf or ascii.
309 !%Option arpes 7
310 !% Full ARPES for semi-periodic systems (vtk).
311 !%Option arpes_cut 8
312 !% ARPES cut on a plane following a zero-weight path in reciprocal space.
313 !%End
314 pesout%what = what
315 call io_function_read_what_how_when(global_namespace, space, pesout%what, pesout%how, pesout%output_interval, &
316 what_tag_in = 'PhotoelectronSpectrumOutput', ignore_error = .true.)
317
318 ! TODO: I think it would be better to move these options in the
319 ! input file to have more flexibility to combine and to keep
320 ! track of them. UDG
321 ! Read options from command line
322 call getopt_photoelectron_spectrum(uestep, uespan,&
323 uthstep, uthspan, uphstep, &
324 uphspan, pol, center, pvec, integrate)
325
326 call getopt_end()
327
328
329 !! set user values
330 if (uestep > 0 .and. uestep > estep) estep = uestep
331 if (uespan(1) > 0) emin = uespan(1)
332 if (uespan(2) > 0) emax = uespan(2)
333
334
335
336 !%Variable PhotoelectronSpectrumResolveStates
337 !%Type block
338 !%Default
339 !%Section Utilities::oct-photoelectron_spectrum
340 !%Description
341 !% If <tt>yes</tt> calculate the photoelectron spectrum resolved in each K.S. state.
342 !% Optionally a range of states can be given as two slot block where the
343 !% first slot is the lower state index and the second is the highest one.
344 !% For example to calculate the spectra from state i to state j:
345 !%
346 !% <tt>%PhotoelectronSpectrumResolveStates
347 !% <br> i | j
348 !% <br>%</tt>
349 !%End
350 st_range(1:2) = (/1, st%nst/)
351 resolve_states = .false.
352 if (parse_block(global_namespace, 'PhotoelectronSpectrumResolveStates', blk) == 0) then
353 if (parse_block_cols(blk,0) < 2) call messages_input_error(global_namespace, 'PhotoelectronSpectrumResolveStates')
354 do idim = 1, 2
355 call parse_block_integer(blk, 0, idim - 1, st_range(idim))
356 end do
357 call parse_block_end(blk)
358 if (abs(st_range(2)-st_range(1)) > 0)resolve_states = .true.
359 else
360 call parse_variable(global_namespace, 'PhotoelectronSpectrumResolveStates', .false., resolve_states)
361 end if
362
363
364 ! Determine the range of k-points used in the PES calculation
365 krng(1) = 1
366 krng(2) = kpoints_number(kpoints)
367
368 if (have_zweight_path) then
369 if (pesout%what(option__photoelectronspectrumoutput__arpes_cut)) then
370 !Use the path only when asked for ARPES on a cutting curve in reciprocal space(the path)
371 use_zweight_path = .true.
372
373 krng(1) = kpoints_number(kpoints) - kpoints%nik_skip + 1
374
375 call messages_print_with_emphasis(msg="Kpoint selection", namespace=global_namespace)
376 write(message(1), '(a)') 'Will use a zero-weight path in reciprocal space with the following points'
377 call messages_info(1)
378
379 kpth_dir = 1
380 pvec = (/0,1,0/)
381
382
383 else
384 use_zweight_path = .false.
385 krng(2) = kpoints_number(kpoints) - kpoints%nik_skip
386
387 end if
388 end if
389
390 call write_kpoints_info(kpoints, krng(1), krng(2))
392
393 nkpt = krng(2) - krng(1) + 1
394
395
396
397 if (use_zweight_path) then
398 llp(1:dim) = llpp(1:dim)
399 llp(kpth_dir) = llpp(kpth_dir) * nkpt
400 else
401 llp(1:dim) = llpp(1:dim)
402 end if
403
404 write(message(1),'(a,i4,i4,i4)') 'Debug : llp = ', llp(1:3)
405 write(message(2),'(a,i4,i4,i4)') 'Debug : llpp = ', llpp(1:3)
406 call messages_info(2, debug_only=.true.)
407
408 safe_allocate(pmesh(1:llp(1), 1:llp(2), 1:llp(3), 1:3 + 1))
409 safe_allocate( pesp(1:llp(1), 1:llp(2), 1:llp(3), 1:st%d%nspin))
410
411 select case (pes_method)
412 case (option__photoelectronspectrum__pes_mask)
413 safe_allocate(lp(1:llpp(1), 1:llpp(2), 1:llpp(3), krng(1):krng(2), 1:3))
414 call pes_mask_pmesh(global_namespace, dim, kpoints, llpp, lg, pmesh, idxzero, krng, lp)
415
416 case (option__photoelectronspectrum__pes_flux)
417 ! Lp is allocated inside pes_flux_pmesh to comply with the
418 ! declinations of the different surfaces
419 safe_allocate(ekin(1:llp(1), 1:llp(2), 1:llp(3)))
420 ekin = m_zero
421 nspin = 1
422 if (st%d%ispin == spin_polarized) nspin = 2
423 call pes_flux_pmesh(pflux, global_namespace, dim, kpoints, llpp, pmesh, idxzero, krng, nspin, lp, ekin)
424 end select
425
426
427 if (.not. need_pmesh) then
428 ! There is no need to use pmesh we just need to sort Lg in place
429 ! in order to have a coordinate ordering coherent with pesP
430 ! NOTE: this works only for the mask_method since Lg is well-defined
431 ! only in this case
432 do idim = 1, dim
433 call sort(lg(1:llp(idim), idim))
434 end do
435 end if
436
437
438 call messages_write('Read PES restart files.')
439 call messages_info()
440
441
442
444
445 write(message(1),'(a,f10.2,a2,f10.2,a2,f10.2,a1)') &
446 "Zenith axis: (",pol(1),", ",pol(2),", ",pol(3),")"
447 call messages_info(1)
448
449
450 ! Convert the grid units
451 if (need_pmesh) then
452 do ii = 1,3
453 do i3 = 1, llp(3)
454 do i2 = 1, llp(2)
455 do i1 = 1, llp(1)
456 pmesh(i1, i2, i3, ii) = units_from_atomic(sqrt(units_out%energy), pmesh(i1, i2, i3, ii))
457 end do
458 end do
459 end do
460 end do
461 end if
462
463 if (resolve_states) then
464 do ist = st_range(1), st_range(2)
465
466 select case (pes_method)
467 case (option__photoelectronspectrum__pes_mask)
468 call pes_mask_map_from_states(restart, st, llpp, pesp, krng, lp, ist)
469 case (option__photoelectronspectrum__pes_flux)
470 call pes_flux_map_from_states(pflux, restart, st, llpp, pesp, krng, lp, ist)
471 end select
472
473 call output_spin_pes()
474 end do
475
476 else
477 ! Read the data
478 ist = 0
479
480 select case (pes_method)
481 case (option__photoelectronspectrum__pes_mask)
482 call pes_mask_map_from_states(restart, st, llpp, pesp, krng, lp)
483 case (option__photoelectronspectrum__pes_flux)
484 call pes_flux_map_from_states(pflux, restart, st, llpp, pesp, krng, lp)
485 end select
486
487 call output_spin_pes()
488
489 end if
490
491
492
493 write(message(1), '(a)') 'Done'
494 call messages_info(1)
495
497
498 call restart%end()
499
500 call states_elec_end(st)
501
502 safe_deallocate_p(ions)
503 call kpoints_end(kpoints)
504
506 call io_end()
507 call messages_end()
508
509 call parser_end()
510 call global_end()
511
512 safe_deallocate_a(pesp)
513 safe_deallocate_a(pmesh)
514 safe_deallocate_a(lp)
515 safe_deallocate_a(ekin)
516 if (.not. need_pmesh .or. pes_method == option__photoelectronspectrum__pes_mask) then
517 safe_deallocate_a(lg)
518 end if
519contains
520
521 function outfile(name, ist, ispin, extension) result(fname)
522 character(len=*), intent(in) :: name
523 integer, intent(in) :: ist
524 integer, intent(in) :: ispin
525 character(len=*), optional, intent(in) :: extension
526 character(len=512) :: fname
527
528 if (ist == 0) then
529 fname = trim(name)
530 else
531 write(fname, '(a,a,i4.4)') trim(name), '-st', ist
532 end if
533
534 if (ispin >0) then
535 write(fname, '(a,a,i1)') trim(fname),'-sp', ispin
536 end if
537
538 if (present(extension) .and. len(extension)>0) then
539 fname = trim(fname)//'.'//trim(extension)
540 end if
541
542 end function outfile
543
544 subroutine output_spin_pes()
545
546 ! Write total quantities (summed over spin)
547 ispin = 0
548 if (st%d%ispin == unpolarized) then
549 pesp_out => pesp(:,:,:,1)
550 call output_pes()
551 else
552 ! Write total quantities (summed over spin)
553 safe_allocate(pesp_out(1:llp(1), 1:llp(2), 1:llp(3)))
554 pesp_out(:,:,:) = pesp(:,:,:,1) + pesp(:,:,:,2)
555
556 call output_pes()
557
558 safe_deallocate_p(pesp_out)
559
560 ! spin-resolved
561 do ispin = 1, st%d%nspin
562 pesp_out => pesp(:,:,:,ispin)
563 call output_pes()
564 end do
565 end if
566 end subroutine output_spin_pes
567
568 subroutine output_pes()
569
570 ! choose what to calculate
571 ! these functions are defined in pes_mask_out_inc.F90
572
573 if (st%d%ispin /= unpolarized .or. ist>0) then
575 end if
576
577 if (ist > 0) then
578 write(message(1), '(a,i4)') 'State = ', ist
579 call messages_info(1)
580 end if
581
582 if (st%d%ispin /= unpolarized) then
583 if (ispin > 0) then
584 write(message(1), '(a,i1)') 'Spin component= ', ispin
585 call messages_info(1)
586 else
587 write(message(1), '(a)') 'Spinless'
588 call messages_info(1)
589 end if
590 end if
591
592 if (ions%latt%nonorthogonal) then
593 coord_system => affine_coordinates_t(global_namespace, space%dim, ions%latt%rlattice_primitive)
594 else
595 coord_system => cartesian_t(global_namespace, space%dim)
596 end if
597
598
599 if (pesout%what(option__photoelectronspectrumoutput__energy_tot)) then
600 call messages_print_with_emphasis(msg="Energy-resolved PES", namespace=global_namespace)
601
602 select case (pes_method)
603 case (option__photoelectronspectrum__pes_mask)
604 call pes_mask_output_power_totalm(pesp_out,outfile('./PES_energy',ist, ispin, 'sum'), &
605 global_namespace, lg, llp, dim, emax, estep, interpolate = .true.)
606 case (option__photoelectronspectrum__pes_flux)
607 call pes_flux_out_energy(pflux, pesp_out, outfile('./PES_energy',ist, ispin, 'sum'), global_namespace, llp, ekin, dim)
608 end select
609
610 end if
611
612 if (pesout%what(option__photoelectronspectrumoutput__energy_angle)) then
613 call messages_print_with_emphasis(msg="Angle- and energy-resolved PES", namespace=global_namespace)
614
615 select case (pes_method)
616 case (option__photoelectronspectrum__pes_mask)
617 call pes_mask_output_ar_polar_m(pesp_out,outfile('./PES_angle_energy',ist, ispin, 'map'), &
618 global_namespace, lg, llp, dim, pol, emax, estep)
619 case (option__photoelectronspectrum__pes_flux)
620 call messages_not_implemented("Angle- and energy-resolved PES for the flux method")
621 end select
622
623
624 end if
625
626 if (pesout%what(option__photoelectronspectrumoutput__velocity_map_cut)) then
627 call messages_print_with_emphasis(msg="Velocity map on a plane", namespace=global_namespace)
628 dir = -1
629 if (sum((pvec-(/1 ,0 ,0/))**2) <= m_epsilon) dir = 1
630 if (sum((pvec-(/0 ,1 ,0/))**2) <= m_epsilon) dir = 2
631 if (sum((pvec-(/0 ,0 ,1/))**2) <= m_epsilon) dir = 3
632
633 if (use_zweight_path) then
634 filename = outfile('PES_velocity_map', ist, ispin, 'path')
635 else
636 filename = outfile('PES_velocity_map', ist, ispin, 'p'//index2axis(dir)//'=0')
637 end if
638
639 if (dir == -1) then
640 write(message(1), '(a)') 'Unrecognized plane. Use -u to change.'
641 call messages_fatal(1)
642 else
643 write(message(1), '(a)') 'Save velocity map on plane: '//index2axis(dir)//" = 0"
644 call messages_info(1)
645 end if
646
647 if (integrate /= integrate_none) then
648 write(message(1), '(a)') 'Integrate on: '//index2var(integrate)
649 call messages_info(1)
650 filename = trim(filename)//'.i_'//trim(index2var(integrate))
651 end if
652
653 if (need_pmesh) then
654 call pes_out_velocity_map_cut(global_namespace, pesp_out, filename, llp, dim, pol, dir, integrate, &
655 pos = idxzero, pmesh = pmesh)
656 else
657 call pes_out_velocity_map_cut(global_namespace, pesp_out, filename, llp, dim, pol, dir, integrate, &
658 pos = idxzero, lk = lg)
659 end if
660 end if
661
662 if (pesout%what(option__photoelectronspectrumoutput__energy_xy)) then
663 call messages_print_with_emphasis(msg="Angle and energy-resolved on a plane", namespace=global_namespace)
664 if (uestep > 0 .and. uestep > estep) then
665 estep = uestep
666 else
667 estep = emax/size(lg,1)
668 end if
669
670 select case (pes_method)
671 case (option__photoelectronspectrum__pes_mask)
672 call pes_mask_output_ar_plane_m(pesp_out,outfile('./PES_energy', ist, ispin, 'map'), &
673 global_namespace, lg, llp, dim, pol, emax, estep)
674 case (option__photoelectronspectrum__pes_flux)
675 call messages_not_implemented("Angle and energy-resolved on a plane for the flux method")
676 end select
677
678 end if
679
680 if (pesout%what(option__photoelectronspectrumoutput__energy_th_ph)) then
681 call messages_print_with_emphasis(msg="PES on spherical cuts", namespace=global_namespace)
682
683 write(message(1), '(a,es19.12,a2,es19.12,2x,a19)') &
684 'Save PES on a spherical cut at E= ',emin,", ",emax, &
685 str_center('['//trim(units_abbrev(units_out%energy)) // ']', 19)
686 call messages_info(1)
687
688 if (uestep > 0 .and. uestep > estep) then
689 estep = uestep
690 else
691 estep = emax/size(lg,1)
692 end if
693
694 select case (pes_method)
695 case (option__photoelectronspectrum__pes_mask)
696 call pes_mask_output_ar_spherical_cut_m(pesp_out,outfile('./PES_sphere', ist, ispin, 'map'), &
697 global_namespace, lg, llp, dim, pol, emin, emax, estep)
698
699 case (option__photoelectronspectrum__pes_flux)
700 call messages_not_implemented("PES on spherical cuts for the flux method")
701 end select
702
703 end if
704
705 if (pesout%what(option__photoelectronspectrumoutput__velocity_map)) then
706
707 call messages_print_with_emphasis(msg="Full velocity map", namespace=global_namespace)
708
709 if (.not. (bitand(pesout%how(option__photoelectronspectrumoutput__velocity_map), option__outputformat__netcdf) /= 0) .and. &
710 .not. (bitand(pesout%how(option__photoelectronspectrumoutput__velocity_map), option__outputformat__vtk) /= 0) .and. &
711 .not. (bitand(pesout%how(option__photoelectronspectrumoutput__velocity_map), option__outputformat__ascii) /= 0)) then
712 message(1) = 'User must specify the format with "OutputFormat".'
713 message(2) = 'Available options are: necdf, vtk, ascii.'
714 call messages_fatal(2)
715
716 end if
717
718
719 filename = outfile('./PES_velocity_map', ist, ispin)
720 if (need_pmesh) then
721 !force vtk output
722! how = io_function_fill_how("VTK")
723 if (bitand(pesout%how(option__photoelectronspectrumoutput__velocity_map), option__outputformat__ascii) /= 0) then
724 call pes_flux_out_vmap(pflux, pesp_out, filename, global_namespace, llp, pmesh, space%dim)
725 else
726 call pes_out_velocity_map(pesp_out, filename, global_namespace, space, lg, llp, &
727 pesout%how(option__photoelectronspectrumoutput__velocity_map), &
728 (/m_one, m_one, m_one/), coord_system, pmesh)
729 end if
730 else
731 call pes_out_velocity_map(pesp_out, filename, global_namespace, space, lg, llp, &
732 pesout%how(option__photoelectronspectrumoutput__velocity_map), &
733 (/m_one, m_one, m_one/), coord_system)
734 end if
735
736 end if
737
738 if (pesout%what(option__photoelectronspectrumoutput__arpes)) then
739 call messages_print_with_emphasis(msg="ARPES", namespace=global_namespace)
740
741 do i3 = 1, llp(3)
742 do i2 = 1, llp(2)
743 do i1 = 1, llp(1)
744 pmesh(i1, i2, i3, dim) = units_from_atomic(units_out%energy, &
745 sign(m_one,pmesh( i1, i2, i3, dim)) * sum(pmesh(i1, i2, i3, 1:dim)**2) / m_two)
746 end do
747 end do
748 end do
749
750 pesout%how(option__photoelectronspectrumoutput__arpes) = io_function_fill_how("VTK")
751
752 call pes_out_velocity_map(pesp_out, outfile('./PES_ARPES', ist, ispin), &
753 global_namespace, space, lg, llp, pesout%how(option__photoelectronspectrumoutput__arpes), &
754 (/m_one, m_one, m_one/), coord_system, pmesh)
755 end if
756
757
758 if (pesout%what(option__photoelectronspectrumoutput__arpes_cut)) then
759 call messages_print_with_emphasis(msg="ARPES cut on reciprocal space path", namespace=global_namespace)
760
761 filename = outfile('./PES_ARPES', ist, ispin, "path")
762 call pes_out_arpes_cut(global_namespace, pesp_out, filename, dim, llp, pmesh, ekin)
763
764 end if
765
766 safe_deallocate_p(coord_system)
767
768 end subroutine output_pes
769
770
771 subroutine write_kpoints_info(kpoints, ikstart, ikend)
772 type(kpoints_t), intent(in) :: kpoints
773 integer, intent(in) :: ikstart
774 integer, intent(in) :: ikend
775
776 integer :: ik, idir
777 character(len=100) :: str_tmp
778
779 push_sub(write_kpoints_info)
780
781 do ik = ikstart, ikend
782 write(message(1),'(i8,1x)') ik
783 write(str_tmp,'(f12.6)') kpoints%get_weight(ik)
784 message(1) = trim(message(1)) // trim(str_tmp)//' |'
785 do idir = 1, kpoints%full%dim
786 write(str_tmp,'(f12.6)') kpoints%reduced%red_point(idir, ik)
787 message(1) = trim(message(1)) // trim(str_tmp)
788 end do
789 message(1) = trim(message(1)) //' |'
790 call messages_info(1)
791 end do
792
793 call messages_info(1)
794
795 pop_sub(write_kpoints_info)
796 end subroutine write_kpoints_info
797
798 subroutine get_laser_polarization(lPol)
799 real(real64), intent(out) :: lPol(:)
800
801 type(block_t) :: blk
802 integer :: no_l
803 complex(real64) :: cPol(1:3)
804
805 push_sub(get_laser_polarization)
806
807 cpol = m_zero
808
809 no_l = 0
810 if (parse_block(global_namespace, 'TDExternalFields', blk) == 0) then
811 no_l = parse_block_n(blk)
812
813 call parse_block_cmplx(blk, 0, 1, cpol(1))
814 call parse_block_cmplx(blk, 0, 2, cpol(2))
815 call parse_block_cmplx(blk, 0, 3, cpol(3))
816
817
818 call parse_block_end(blk)
819 end if
820
821 lpol(:) = abs(cpol)
822
823 if (no_l > 1) then
824 message(1) = "There is more than one external field. Polarization will be selected"
825 message(2) = "from the first field. Use -V to change axis."
826 call messages_info(2)
827 end if
828
830 end subroutine get_laser_polarization
831
832 character(5) pure function index2var(ivar) result(ch)
833 integer, intent(in) :: ivar
834
835 select case (ivar)
836 case (integrate_phi)
837 ch = 'phi'
838 case (integrate_theta)
839 ch = 'theta'
840 case (integrate_r)
841 ch = 'r'
842 case (integrate_kx)
843 ch = 'kx'
844 case (integrate_ky)
845 ch = 'ky'
846 case (integrate_kz)
847 ch = 'kz'
848 case default
849 write(ch,'(i1)') ivar
850 end select
851 end function index2var
852
853
854
855
856
857
858end program photoelectron_spectrum
859
860!! Local Variables:
861!! mode: f90
862!! coding: utf-8
863!! End:
This is the common interface to a sorting routine. It performs the shell algorithm,...
Definition: sort.F90:156
This module handles the calculation mode.
integer, parameter, public p_strategy_domains
parallelization in domains
subroutine, public getopt_init(ierr)
Initializes the getopt machinery. Must be called before attempting to parse the options....
subroutine, public getopt_end
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spin_polarized
real(real64), parameter, public m_two
Definition: global.F90:202
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
Definition: global.F90:494
real(real64), parameter, public m_zero
Definition: global.F90:200
type(mpi_comm), parameter, public serial_dummy_comm
Alias MPI_COMM_UNDEFINED for the specific use case of initialising Octopus utilities with no MPI supp...
Definition: global.F90:294
subroutine, public init_octopus_globals(comm)
Initialise Octopus-specific global constants and files. This routine performs no initialisation calls...
Definition: global.F90:432
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_one
Definition: global.F90:201
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)
integer(int64) function, public io_function_fill_how(where)
Use this function to quickly plot functions for debugging purposes: call dio_function_output(io_funct...
Definition: io.F90:116
subroutine, public io_init(defaults)
If the argument defaults is present and set to true, then the routine will not try to read anything f...
Definition: io.F90:165
subroutine, public io_end()
Definition: io.F90:271
subroutine, public kpoints_end(this)
Definition: kpoints.F90:1059
subroutine, public kpoints_init(this, namespace, symm, dim, periodic_dim, latt)
Definition: kpoints.F90:416
integer pure function, public kpoints_number(this)
Definition: kpoints.F90:1213
subroutine, public messages_end()
Definition: messages.F90:273
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_init(output_dir)
Definition: messages.F90:220
subroutine, public messages_new_line()
Definition: messages.F90:1089
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_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:273
type(namespace_t), public global_namespace
Definition: namespace.F90:135
subroutine, public parser_init()
Initialise the Octopus parser.
Definition: parser.F90:410
subroutine, public parser_end()
End the Octopus parser.
Definition: parser.F90:442
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public pes_flux_map_from_states(this, restart, st, ll, pesP, krng, Lp, istin)
Definition: pes_flux.F90:3380
subroutine, public pes_flux_out_energy(this, pesK, file, namespace, ll, Ekin, dim)
Definition: pes_flux.F90:4038
subroutine, public pes_flux_pmesh(this, namespace, dim, kpoints, ll, pmesh, idxZero, krng, nspin, Lp, Ekin)
Definition: pes_flux.F90:3339
subroutine, public pes_flux_reciprocal_mesh_gen(this, namespace, space, st, kpoints, comm, post)
Definition: pes_flux.F90:857
subroutine, public pes_flux_out_vmap(this, pesK, file, namespace, ll, pmesh, dim)
Definition: pes_flux.F90:4128
integer, parameter, public integrate_r
Definition: pes_mask.F90:265
integer, parameter, public integrate_kx
Definition: pes_mask.F90:265
subroutine, public pes_mask_pmesh(namespace, dim, kpoints, ll, LG, pmesh, idxZero, krng, Lp)
Definition: pes_mask.F90:1540
subroutine, public pes_mask_output_power_totalm(pesK, file, namespace, Lk, ll, dim, Emax, Estep, interpolate)
Definition: pes_mask.F90:3154
integer, parameter, public integrate_phi
Definition: pes_mask.F90:265
subroutine, public pes_mask_output_ar_spherical_cut_m(pesK, file, namespace, Lk, ll, dim, dir, Emin, Emax, Estep)
Definition: pes_mask.F90:2883
integer, parameter, public integrate_none
Definition: pes_mask.F90:265
integer, parameter, public integrate_theta
Definition: pes_mask.F90:265
subroutine, public pes_mask_output_ar_plane_m(pesK, file, namespace, Lk, ll, dim, dir, Emax, Estep)
Definition: pes_mask.F90:2753
subroutine, public pes_mask_map_from_states(restart, st, ll, pesK, krng, Lp, istin)
Definition: pes_mask.F90:1780
integer, parameter, public integrate_ky
Definition: pes_mask.F90:265
integer, parameter, public integrate_kz
Definition: pes_mask.F90:265
subroutine, public pes_mask_read_info(dir, namespace, dim, Emax, Estep, ll, Lk, RR)
Read pes info.
Definition: pes_mask.F90:3477
subroutine, public pes_mask_output_ar_polar_m(pesK, file, namespace, Lk, ll, dim, dir, Emax, Estep)
Definition: pes_mask.F90:2634
subroutine, public pes_out_velocity_map_cut(namespace, pesK, file, ll, dim, pol, dir, integrate, pos, Lk, pmesh)
Definition: pes_out.F90:294
subroutine, public pes_out_velocity_map(pesK, file, namespace, space, Lk, ll, how, spacing, coord_system, pmesh)
Definition: pes_out.F90:164
subroutine, public pes_out_arpes_cut(namespace, arpes, file, dim, ll, pmesh, Ekin)
Definition: pes_out.F90:218
subroutine, public profiling_end(namespace)
Definition: profiling.F90:415
subroutine, public profiling_init(namespace)
Create profiling subdirectory.
Definition: profiling.F90:257
integer, parameter, public restart_td
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:184
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:119
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_init(st, namespace, space, valence_charge, kpoints, calc_mode_id)
Initialize a new states_elec_t object.
character(len=80) function, public str_center(s_in, l_in)
puts space around string, so that it is centered
Definition: string.F90:176
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
subroutine, public unit_system_init(namespace)
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:205
subroutine write_kpoints_info(kpoints, ikstart, ikend)
subroutine get_laser_polarization(lPol)
subroutine output_spin_pes()
character(5) pure function index2var(ivar)
program photoelectron_spectrum
subroutine output_pes()
character(len=512) function outfile(name, ist, ispin, extension)
Extension of space that contains the knowledge of the spin dimension.
int true(void)