26 USE gx_ac,
ONLY: create_thiele_pade, &
27 evaluate_thiele_pade_at, &
30 USE gx_minimax,
ONLY: gx_minimax_grid
33#include "./base/base_uses.f90"
39 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'greenx_interface'
58 SUBROUTINE greenx_refine_pade(e_min, e_max, x_eval, number_of_simulation_steps, number_of_pade_points, &
59 logger, ft_section, bse_unit, omega_series, ft_full_series)
60 REAL(kind=
dp),
INTENT(IN) :: e_min, e_max
61 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: x_eval
62 INTEGER,
INTENT(IN) :: number_of_simulation_steps, number_of_pade_points
65 INTEGER,
INTENT(IN) :: bse_unit
66 REAL(kind=
dp),
DIMENSION(number_of_simulation_steps + 2),
INTENT(INOUT) :: omega_series
67 REAL(kind=
dp),
DIMENSION(6, number_of_simulation_steps + 2),
INTENT(INOUT) :: ft_full_series
70 COMPLEX(kind=dp),
DIMENSION(:),
ALLOCATABLE :: omega_complex, &
72 COMPLEX(kind=dp),
DIMENSION(:, :),
ALLOCATABLE :: moments_eval_complex
75 IF (bse_unit > 0)
WRITE (bse_unit,
'(A10,A27,E23.8E3,E20.8E3)') &
76 " PADE_FT| ",
"Evaluation grid bounds [eV]", e_min, e_max
77 ALLOCATE (omega_complex(number_of_simulation_steps + 2))
78 ALLOCATE (moments_ft_complex(number_of_simulation_steps + 2))
79 ALLOCATE (moments_eval_complex(3, number_of_pade_points))
80 omega_complex(:) = cmplx(omega_series(:), 0.0, kind=
dp)
82 moments_ft_complex(:) = cmplx(ft_full_series(2*i - 1, :), &
83 ft_full_series(2*i, :), &
87 CALL greenx_refine_ft(e_min, e_max, omega_complex, moments_ft_complex, x_eval, moments_eval_complex(i, :))
91 file_form=
"FORMATTED", file_position=
"REWIND")
93 DO i = 1, number_of_pade_points
94 WRITE (ft_unit,
'(E20.8E3,E20.8E3,E20.8E3,E20.8E3,E20.8E3,E20.8E3,E20.8E3)') &
95 REAL(x_eval(i)),
REAL(moments_eval_complex(1, i)), aimag(moments_eval_complex(1, i)), &
96 REAL(moments_eval_complex(2, i)), aimag(moments_eval_complex(2, i)), &
97 REAL(moments_eval_complex(3, i)), aimag(moments_eval_complex(3, i))
101 DEALLOCATE (omega_complex)
102 DEALLOCATE (moments_ft_complex)
103 DEALLOCATE (moments_eval_complex)
105 IF (bse_unit > 0)
WRITE (bse_unit,
'(A10,A70)') &
106 " PADE_FT| ",
"GreenX library is not available. Refinement is skipped"
110 mark_used(number_of_simulation_steps)
111 mark_used(number_of_pade_points)
113 mark_used(ft_section)
114 mark_used(omega_series)
115 mark_used(ft_full_series)
132 INTEGER,
INTENT(IN) :: bse_unit
133 INTEGER,
DIMENSION(:, :),
POINTER :: pol_elements
134 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: x_eval
135 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: polarizability_refined
137 INTEGER :: pol_unit, &
140 n_elems =
SIZE(pol_elements, 1)
143 file_form=
"FORMATTED", file_position=
"REWIND")
145 IF (pol_unit > 0)
THEN
146 IF (pol_unit == bse_unit)
THEN
148 WRITE (pol_unit,
'(A21)', advance=
"no")
" POLARIZABILITY_PADE|"
151 WRITE (pol_unit,
'(A1,A19)', advance=
"no")
"#",
"omega [a.u.]"
154 WRITE (pol_unit,
'(A20)', advance=
"no")
"Energy [eV]"
156 DO k = 1, n_elems - 1
157 WRITE (pol_unit,
'(A16,I2,I2,A16,I2,I2)', advance=
"no") &
158 "Real pol.", pol_elements(k, 1), pol_elements(k, 2), &
159 "Imag pol.", pol_elements(k, 1), pol_elements(k, 2)
161 WRITE (pol_unit,
'(A16,I2,I2,A16,I2,I2)') &
162 "Real pol.", pol_elements(n_elems, 1), pol_elements(n_elems, 2), &
163 "Imag pol.", pol_elements(n_elems, 1), pol_elements(n_elems, 2)
164 DO i = 1,
SIZE(x_eval)
165 IF (pol_unit == bse_unit)
THEN
167 WRITE (pol_unit,
'(A21)', advance=
"no")
" POLARIZABILITY_PADE|"
170 WRITE (pol_unit,
'(E20.8E3)', advance=
"no") real(x_eval(i), kind=
dp)
173 WRITE (pol_unit,
'(E20.8E3)', advance=
"no") real(x_eval(i), kind=
dp)*
evolt
174 DO k = 1, n_elems - 1
175 WRITE (pol_unit,
'(E20.8E3,E20.8E3)', advance=
"no") &
176 REAL(polarizability_refined(k, i)), aimag(polarizability_refined(k, i))
179 WRITE (pol_unit,
'(E20.8E3,E20.8E3)') &
180 REAL(polarizability_refined(n_elems, i)), aimag(polarizability_refined(n_elems, i))
186 mark_used(pol_section)
188 mark_used(pol_elements)
190 mark_used(polarizability_refined)
203 SUBROUTINE greenx_refine_ft(fit_e_min, fit_e_max, x_fit, y_fit, x_eval, y_eval, n_pade_opt)
204 REAL(kind=
dp) :: fit_e_min, &
206 COMPLEX(kind=dp),
DIMENSION(:) :: x_fit, &
210 INTEGER,
OPTIONAL :: n_pade_opt
211#if defined (__GREENX)
212 INTEGER :: fit_start, &
219 TYPE(params) :: pade_params
222 max_fit =
SIZE(x_fit)
223 n_eval =
SIZE(x_eval)
231 IF (fit_e_max < 0) fit_end = max_fit
233 IF (fit_start == -1 .AND. real(x_fit(i)) >= fit_e_min) fit_start = i
234 IF (fit_end == -1 .AND. real(x_fit(i)) > fit_e_max) fit_end = i - 1
235 IF (fit_start > 0 .AND. fit_end > 0)
EXIT
237 IF (fit_start == -1) fit_start = 1
238 IF (fit_end == -1) fit_end = max_fit
239 n_fit = fit_end - fit_start + 1
242 IF (
PRESENT(n_pade_opt)) n_pade = n_pade_opt
245 IF (n_pade > 1000)
THEN
246 cpwarn(é
"More then 1000 Pad parameters requested - may reduce with FIT_E_MIN/FIT_E_MAX.")
250 pade_params = create_thiele_pade(n_pade, x_fit(fit_start:fit_end), y_fit(fit_start:fit_end), &
251 enforce_symmetry=
"conjugate")
254 y_eval(1:n_eval) = evaluate_thiele_pade_at(pade_params, x_eval)
256 CALL free_params(pade_params)
265 mark_used(n_pade_opt)
266 cpabort(
"Calls to GreenX require CP2K to be compiled with support for GreenX.")
287 tau_tj, tau_wj, regularization_minimax, &
288 tj, wj, weights_cos_tf_t_to_w, &
289 weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, ierr)
291 INTEGER,
INTENT(IN) :: unit_nr, num_integ_points
292 REAL(kind=
dp),
INTENT(IN) :: emin, emax
293 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
294 INTENT(OUT) :: tau_tj, tau_wj
295 REAL(kind=
dp),
INTENT(IN) :: regularization_minimax
296 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
297 INTENT(INOUT) :: tj, wj
298 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
299 INTENT(OUT) :: weights_cos_tf_t_to_w, &
300 weights_cos_tf_w_to_t, &
301 weights_sin_tf_t_to_w
302 INTEGER,
INTENT(OUT) :: ierr
303#if defined (__GREENX)
305 REAL(kind=
dp) :: cosft_duality_error_greenx, &
308 CALL gx_minimax_grid(num_integ_points, emin, emax, tau_tj, tau_wj, tj, wj, &
309 weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, &
310 max_errors_greenx, cosft_duality_error_greenx, ierr, &
311 bare_cos_sin_weights=.true., &
312 regularization=regularization_minimax)
316 IF (unit_nr > 0)
THEN
317 WRITE (unit=unit_nr, fmt=
"(T3,A,T75,i6)") &
318 "GREENX MINIMAX_INFO| Number of integration points:", num_integ_points
319 WRITE (unit=unit_nr, fmt=
"(T3,A,T61,3F20.7)") &
320 "GREENX MINIMAX_INFO| Gap (Emin):", emin
321 WRITE (unit=unit_nr, fmt=
"(T3,A,T61,3F20.7)") &
322 "GREENX MINIMAX_INFO| Maximum eigenvalue difference (Emax):", emax
323 WRITE (unit=unit_nr, fmt=
"(T3,A,T61,3F20.4)") &
324 "GREENX MINIMAX_INFO| Energy range (Emax/Emin):", emax/emin
325 WRITE (unit=unit_nr, fmt=
"(T3,A,T54,A,T72,A)") &
326 "GREENX MINIMAX_INFO| Frequency grid (scaled):",
"Weights",
"Abscissas"
327 DO gi = 1, num_integ_points
328 WRITE (unit=unit_nr, fmt=
"(T41,F20.10,F20.10)") wj(gi), tj(gi)
330 WRITE (unit=unit_nr, fmt=
"(T3,A,T54,A,T72,A)") &
331 "GREENX MINIMAX_INFO| Time grid (scaled):",
"Weights",
"Abscissas"
332 DO gi = 1, num_integ_points
333 WRITE (unit=unit_nr, fmt=
"(T41,F20.10,F20.10)") tau_wj(gi), tau_tj(gi)
338 IF (unit_nr > 0)
THEN
339 WRITE (unit=unit_nr, fmt=
"(T3,A,T75)") &
340 "GREENX MINIMAX_INFO| Grid not available, use internal CP2K grids"
343 IF (
ALLOCATED(tau_tj))
THEN
346 IF (
ALLOCATED(tau_wj))
THEN
349 IF (
ALLOCATED(tj))
THEN
352 IF (
ALLOCATED(wj))
THEN
355 IF (
ALLOCATED(weights_cos_tf_t_to_w))
THEN
356 DEALLOCATE (weights_cos_tf_t_to_w)
358 IF (
ALLOCATED(weights_cos_tf_w_to_t))
THEN
359 DEALLOCATE (weights_cos_tf_w_to_t)
361 IF (
ALLOCATED(weights_sin_tf_t_to_w))
THEN
362 DEALLOCATE (weights_sin_tf_t_to_w)
368 mark_used(num_integ_points)
373 mark_used(regularization_minimax)
376 mark_used(weights_cos_tf_t_to_w)
377 mark_used(weights_cos_tf_w_to_t)
378 mark_used(weights_sin_tf_t_to_w)
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
integer, parameter, public low_print_level
integer, parameter, public medium_print_level
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
Interface to the Greenx library.
subroutine, public greenx_refine_ft(fit_e_min, fit_e_max, x_fit, y_fit, x_eval, y_eval, n_pade_opt)
Refines the FT grid using Padé approximants.
subroutine, public greenx_refine_pade(e_min, e_max, x_eval, number_of_simulation_steps, number_of_pade_points, logger, ft_section, bse_unit, omega_series, ft_full_series)
Refines Pade approximants using GreenX, skips this step if GreenX is not available.
subroutine, public greenx_output_polarizability(logger, pol_section, bse_unit, pol_elements, x_eval, polarizability_refined)
Outputs the isotropic polarizability tensor element alpha _ ij = mu_i(omega)/E_j(omega),...
subroutine, public greenx_get_minimax_grid(unit_nr, num_integ_points, emin, emax, tau_tj, tau_wj, regularization_minimax, tj, wj, weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, ierr)
...
Defines the basic variable types.
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition of physical constants:
real(kind=dp), parameter, public evolt
type of a logger, at the moment it contains just a print level starting at which level it should be l...