(git:98357aa)
Loading...
Searching...
No Matches
xray_diffraction.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \par Literature
10!> M. Krack, A. Gambirasio, and M. Parrinello,
11!> "Ab-initio x-ray scattering of liquid water",
12!> J. Chem. Phys. 117, 9409 (2002)
13!> \author Matthias Krack
14!> \date 30.11.2005
15! **************************************************************************************************
18 USE bibliography, ONLY: krack2002,&
19 cite_reference
22 USE kinds, ONLY: dp,&
23 int_8
24 USE mathconstants, ONLY: twopi
28 USE physcon, ONLY: angstrom
29 USE pw_env_types, ONLY: pw_env_get,&
31 USE pw_grids, ONLY: get_pw_grid_info
32 USE pw_methods, ONLY: pw_zero
34 USE pw_types, ONLY: pw_c1d_gs_type
38 USE qs_rho_types, ONLY: qs_rho_type
39 USE util, ONLY: sort
40#include "./base/base_uses.f90"
41
42 IMPLICIT NONE
43
44 PRIVATE
45
46 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xray_diffraction'
47
50
51CONTAINS
52
53! **************************************************************************************************
54!> \brief Calculate the coherent X-ray diffraction spectrum using the total
55!> electronic density in reciprocal space (g-space).
56!> \param qs_env ...
57!> \param unit_number ...
58!> \param q_max ...
59!> \date 30.11.2005
60!> \author Matthias Krack
61! **************************************************************************************************
62 SUBROUTINE xray_diffraction_spectrum(qs_env, unit_number, q_max)
63
64 TYPE(qs_environment_type), POINTER :: qs_env
65 INTEGER, INTENT(IN) :: unit_number
66 REAL(kind=dp), INTENT(IN) :: q_max
67
68 CHARACTER(LEN=*), PARAMETER :: routinen = 'xray_diffraction_spectrum'
69 INTEGER, PARAMETER :: nblock = 100
70
71 INTEGER :: handle, i, ig, ig_shell, ipe, ishell, &
72 jg, ng, npe, nshell, nshell_gather
73 INTEGER(KIND=int_8) :: ngpts
74 INTEGER, DIMENSION(3) :: npts
75 INTEGER, DIMENSION(:), POINTER :: aux_index, ng_shell, ng_shell_gather, &
76 nshell_pe, offset_pe
77 REAL(kind=dp) :: cutoff, f, f2, q, rho_hard, rho_soft, &
78 rho_total
79 REAL(kind=dp), DIMENSION(3) :: dg, dr
80 REAL(kind=dp), DIMENSION(:), POINTER :: f2sum, f2sum_gather, f4sum, f4sum_gather, fmax, &
81 fmax_gather, fmin, fmin_gather, fsum, fsum_gather, gsq, q_shell, q_shell_gather
82 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
83 TYPE(dft_control_type), POINTER :: dft_control
84 TYPE(mp_para_env_type), POINTER :: para_env
85 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
86 TYPE(pw_c1d_gs_type) :: rhotot_elec_gspace
87 TYPE(pw_env_type), POINTER :: pw_env
88 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
89 TYPE(qs_rho_type), POINTER :: rho
90 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
91
92 cpassert(ASSOCIATED(qs_env))
93
94 CALL timeset(routinen, handle)
95
96 NULLIFY (atomic_kind_set)
97 NULLIFY (aux_index)
98 NULLIFY (auxbas_pw_pool)
99 NULLIFY (dft_control)
100 NULLIFY (f2sum)
101 NULLIFY (f2sum_gather)
102 NULLIFY (f4sum)
103 NULLIFY (f4sum_gather)
104 NULLIFY (fmax)
105 NULLIFY (fmax_gather)
106 NULLIFY (fmin)
107 NULLIFY (fmin_gather)
108 NULLIFY (fsum)
109 NULLIFY (fsum_gather)
110 NULLIFY (gsq)
111 NULLIFY (ng_shell)
112 NULLIFY (ng_shell_gather)
113 NULLIFY (nshell_pe)
114 NULLIFY (offset_pe)
115 NULLIFY (para_env)
116 NULLIFY (particle_set)
117 NULLIFY (pw_env)
118 NULLIFY (q_shell)
119 NULLIFY (q_shell_gather)
120 NULLIFY (rho)
121 NULLIFY (rho_atom_set)
122
123 CALL cite_reference(krack2002)
124
125 CALL get_qs_env(qs_env=qs_env, &
126 atomic_kind_set=atomic_kind_set, &
127 dft_control=dft_control, &
128 para_env=para_env, &
129 particle_set=particle_set, &
130 pw_env=pw_env, &
131 rho=rho, &
132 rho_atom_set=rho_atom_set)
133
134 CALL pw_env_get(pw_env=pw_env, &
135 auxbas_pw_pool=auxbas_pw_pool)
136
137 npe = para_env%num_pe
138
139 ! Plane waves grid to assemble the total electronic density
140
141 CALL auxbas_pw_pool%create_pw(pw=rhotot_elec_gspace)
142 CALL pw_zero(rhotot_elec_gspace)
143
144 CALL get_pw_grid_info(pw_grid=rhotot_elec_gspace%pw_grid, &
145 dr=dr, &
146 npts=npts, &
147 cutoff=cutoff, &
148 ngpts=ngpts, &
149 gsquare=gsq)
150
151 dg(:) = twopi/(npts(:)*dr(:))
152
153 ! Build the total electronic density in reciprocal space
154
155 CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
156 auxbas_pw_pool=auxbas_pw_pool, &
157 rhotot_elec_gspace=rhotot_elec_gspace, &
158 q_max=q_max, &
159 rho_hard=rho_hard, &
160 rho_soft=rho_soft)
161
162 rho_total = rho_hard + rho_soft
163
164 ! Calculate the coherent X-ray spectrum
165
166 ! Now we have to gather the data from all processes, since each
167 ! process has only worked his sub-grid
168
169 ! Scan the g-vector shells
170
171 CALL reallocate(q_shell, 1, nblock)
172 CALL reallocate(ng_shell, 1, nblock)
173
174 ng = SIZE(gsq)
175
176 jg = 1
177 nshell = 1
178 q_shell(1) = sqrt(gsq(1))
179 ng_shell(1) = 1
180
181 DO ig = 2, ng
182 cpassert(gsq(ig) >= gsq(jg))
183 IF (abs(gsq(ig) - gsq(jg)) > 1.0e-12_dp) THEN
184 nshell = nshell + 1
185 IF (nshell > SIZE(q_shell)) THEN
186 CALL reallocate(q_shell, 1, SIZE(q_shell) + nblock)
187 CALL reallocate(ng_shell, 1, SIZE(ng_shell) + nblock)
188 END IF
189 q = sqrt(gsq(ig))
190 IF (q > q_max) THEN
191 nshell = nshell - 1
192 EXIT
193 END IF
194 q_shell(nshell) = q
195 ng_shell(nshell) = 1
196 jg = ig
197 ELSE
198 ng_shell(nshell) = ng_shell(nshell) + 1
199 END IF
200 END DO
201
202 CALL reallocate(q_shell, 1, nshell)
203 CALL reallocate(ng_shell, 1, nshell)
204 CALL reallocate(fmin, 1, nshell)
205 CALL reallocate(fmax, 1, nshell)
206 CALL reallocate(fsum, 1, nshell)
207 CALL reallocate(f2sum, 1, nshell)
208 CALL reallocate(f4sum, 1, nshell)
209
210 ig = 0
211 DO ishell = 1, nshell
212 fmin(ishell) = huge(0.0_dp)
213 fmax(ishell) = 0.0_dp
214 fsum(ishell) = 0.0_dp
215 f2sum(ishell) = 0.0_dp
216 f4sum(ishell) = 0.0_dp
217 DO ig_shell = 1, ng_shell(ishell)
218 f = abs(rhotot_elec_gspace%array(ig + ig_shell))
219 fmin(ishell) = min(fmin(ishell), f)
220 fmax(ishell) = max(fmax(ishell), f)
221 fsum(ishell) = fsum(ishell) + f
222 f2 = f*f
223 f2sum(ishell) = f2sum(ishell) + f2
224 f4sum(ishell) = f4sum(ishell) + f2*f2
225 END DO
226 ig = ig + ng_shell(ishell)
227 END DO
228
229 CALL reallocate(nshell_pe, 0, npe - 1)
230 CALL reallocate(offset_pe, 0, npe - 1)
231
232 ! Root (source) process gathers the number of shell of each process
233
234 CALL para_env%gather(nshell, nshell_pe)
235
236 ! Only the root process which has to print the full spectrum has to
237 ! allocate here the receive buffers with their real sizes
238
239 IF (unit_number > 0) THEN
240 nshell_gather = sum(nshell_pe)
241 offset_pe(0) = 0
242 DO ipe = 1, npe - 1
243 offset_pe(ipe) = offset_pe(ipe - 1) + nshell_pe(ipe - 1)
244 END DO
245 ELSE
246 nshell_gather = 1 ! dummy value for the non-root processes
247 END IF
248
249 CALL reallocate(q_shell_gather, 1, nshell_gather)
250 CALL reallocate(ng_shell_gather, 1, nshell_gather)
251 CALL reallocate(fmin_gather, 1, nshell_gather)
252 CALL reallocate(fmax_gather, 1, nshell_gather)
253 CALL reallocate(fsum_gather, 1, nshell_gather)
254 CALL reallocate(f2sum_gather, 1, nshell_gather)
255 CALL reallocate(f4sum_gather, 1, nshell_gather)
256
257 CALL para_env%gatherv(q_shell, q_shell_gather, nshell_pe, offset_pe)
258 CALL para_env%gatherv(ng_shell, ng_shell_gather, nshell_pe, offset_pe)
259 CALL para_env%gatherv(fmax, fmax_gather, nshell_pe, offset_pe)
260 CALL para_env%gatherv(fmin, fmin_gather, nshell_pe, offset_pe)
261 CALL para_env%gatherv(fsum, fsum_gather, nshell_pe, offset_pe)
262 CALL para_env%gatherv(f2sum, f2sum_gather, nshell_pe, offset_pe)
263 CALL para_env%gatherv(f4sum, f4sum_gather, nshell_pe, offset_pe)
264
265 IF (ASSOCIATED(offset_pe)) THEN
266 DEALLOCATE (offset_pe)
267 END IF
268
269 IF (ASSOCIATED(nshell_pe)) THEN
270 DEALLOCATE (nshell_pe)
271 END IF
272
273 ! Print X-ray diffraction spectrum (I/O node only)
274
275 IF (unit_number > 0) THEN
276
277 CALL reallocate(aux_index, 1, nshell_gather)
278
279 ! Sort the gathered shells
280
281 CALL sort(q_shell_gather, nshell_gather, aux_index)
282
283 ! Allocate final arrays of sufficient size, i.e. nshell_gather
284 ! is always greater or equal the final nshell value
285
286 CALL reallocate(q_shell, 1, nshell_gather)
287 CALL reallocate(ng_shell, 1, nshell_gather)
288 CALL reallocate(fmin, 1, nshell_gather)
289 CALL reallocate(fmax, 1, nshell_gather)
290 CALL reallocate(fsum, 1, nshell_gather)
291 CALL reallocate(f2sum, 1, nshell_gather)
292 CALL reallocate(f4sum, 1, nshell_gather)
293
294 jg = 1
295 nshell = 1
296 q_shell(1) = q_shell_gather(1)
297 i = aux_index(1)
298 ng_shell(1) = ng_shell_gather(i)
299 fmin(1) = fmin_gather(i)
300 fmax(1) = fmax_gather(i)
301 fsum(1) = fsum_gather(i)
302 f2sum(1) = f2sum_gather(i)
303 f4sum(1) = f4sum_gather(i)
304
305 DO ig = 2, nshell_gather
306 i = aux_index(ig)
307 IF (abs(q_shell_gather(ig) - q_shell_gather(jg)) > 1.0e-12_dp) THEN
308 nshell = nshell + 1
309 q_shell(nshell) = q_shell_gather(ig)
310 ng_shell(nshell) = ng_shell_gather(i)
311 fmin(nshell) = fmin_gather(i)
312 fmax(nshell) = fmax_gather(i)
313 fsum(nshell) = fsum_gather(i)
314 f2sum(nshell) = f2sum_gather(i)
315 f4sum(nshell) = f4sum_gather(i)
316 jg = ig
317 ELSE
318 ng_shell(nshell) = ng_shell(nshell) + ng_shell_gather(i)
319 fmin(nshell) = min(fmin(nshell), fmin_gather(i))
320 fmax(nshell) = max(fmax(nshell), fmax_gather(i))
321 fsum(nshell) = fsum(nshell) + fsum_gather(i)
322 f2sum(nshell) = f2sum(nshell) + f2sum_gather(i)
323 f4sum(nshell) = f4sum(nshell) + f4sum_gather(i)
324 END IF
325 END DO
326
327 ! The auxiliary index array is no longer needed now
328
329 IF (ASSOCIATED(aux_index)) THEN
330 DEALLOCATE (aux_index)
331 END IF
332
333 ! Allocate the final arrays for printing with their real size
334
335 CALL reallocate(q_shell, 1, nshell)
336 CALL reallocate(ng_shell, 1, nshell)
337 CALL reallocate(fmin, 1, nshell)
338 CALL reallocate(fmax, 1, nshell)
339 CALL reallocate(fsum, 1, nshell)
340 CALL reallocate(f2sum, 1, nshell)
341 CALL reallocate(f4sum, 1, nshell)
342
343 ! Write the X-ray diffraction spectrum to the specified file
344
345 WRITE (unit=unit_number, fmt="(A)") &
346 "#", &
347 "# Coherent X-ray diffraction spectrum", &
348 "#"
349 WRITE (unit=unit_number, fmt="(A,1X,F20.10)") &
350 "# Soft electronic charge (G-space) :", rho_soft, &
351 "# Hard electronic charge (G-space) :", rho_hard, &
352 "# Total electronic charge (G-space):", rho_total, &
353 "# Density cutoff [Rydberg] :", 2.0_dp*cutoff, &
354 "# q(min) [1/Angstrom] :", q_shell(2)/angstrom, &
355 "# q(max) [1/Angstrom] :", q_shell(nshell)/angstrom, &
356 "# q(max) [1/Angstrom] (requested) :", q_max/angstrom
357 WRITE (unit=unit_number, fmt="(A,2X,I8)") &
358 "# Number of g-vectors (grid points):", ngpts, &
359 "# Number of g-vector shells :", nshell
360 WRITE (unit=unit_number, fmt="(A,3(1X,I6))") &
361 "# Grid size (a,b,c) :", npts(1:3)
362 WRITE (unit=unit_number, fmt="(A,3F7.3)") &
363 "# dg [1/Angstrom] :", dg(1:3)/angstrom, &
364 "# dr [Angstrom] :", dr(1:3)*angstrom
365 WRITE (unit=unit_number, fmt="(A)") &
366 "#", &
367 "# shell points q [1/A] <|F(q)|^2> Min(|F(q)|)"// &
368 " Max(|F(q)|) <|F(q)|>^2 <|F(q)|^4>"
369
370 DO ishell = 1, nshell
371 WRITE (unit=unit_number, fmt="(T2,I6,2X,I6,5(1X,F15.6),1X,ES15.6)") &
372 ishell, &
373 ng_shell(ishell), &
374 q_shell(ishell)/angstrom, &
375 f2sum(ishell)/real(ng_shell(ishell), kind=dp), &
376 fmin(ishell), &
377 fmax(ishell), &
378 (fsum(ishell)/real(ng_shell(ishell), kind=dp))**2, &
379 f4sum(ishell)/real(ng_shell(ishell), kind=dp)
380 END DO
381
382 END IF
383
384 ! Release work storage
385
386 IF (ASSOCIATED(fmin)) THEN
387 DEALLOCATE (fmin)
388 END IF
389
390 IF (ASSOCIATED(fmax)) THEN
391 DEALLOCATE (fmax)
392 END IF
393
394 IF (ASSOCIATED(fsum)) THEN
395 DEALLOCATE (fsum)
396 END IF
397
398 IF (ASSOCIATED(f2sum)) THEN
399 DEALLOCATE (f2sum)
400 END IF
401
402 IF (ASSOCIATED(f4sum)) THEN
403 DEALLOCATE (f4sum)
404 END IF
405
406 IF (ASSOCIATED(ng_shell)) THEN
407 DEALLOCATE (ng_shell)
408 END IF
409
410 IF (ASSOCIATED(q_shell)) THEN
411 DEALLOCATE (q_shell)
412 END IF
413
414 IF (ASSOCIATED(fmin_gather)) THEN
415 DEALLOCATE (fmin_gather)
416 END IF
417
418 IF (ASSOCIATED(fmax_gather)) THEN
419 DEALLOCATE (fmax_gather)
420 END IF
421
422 IF (ASSOCIATED(fsum_gather)) THEN
423 DEALLOCATE (fsum_gather)
424 END IF
425
426 IF (ASSOCIATED(f2sum_gather)) THEN
427 DEALLOCATE (f2sum_gather)
428 END IF
429
430 IF (ASSOCIATED(f4sum_gather)) THEN
431 DEALLOCATE (f4sum_gather)
432 END IF
433
434 IF (ASSOCIATED(ng_shell_gather)) THEN
435 DEALLOCATE (ng_shell_gather)
436 END IF
437
438 IF (ASSOCIATED(q_shell_gather)) THEN
439 DEALLOCATE (q_shell_gather)
440 END IF
441
442 CALL auxbas_pw_pool%give_back_pw(rhotot_elec_gspace)
443
444 CALL timestop(handle)
445
446 END SUBROUTINE xray_diffraction_spectrum
447
448END MODULE xray_diffraction
Define the atomic kind types and their sub types.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public krack2002
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
GAPW reciprocal-space reconstruction and its discrete adjoint.
subroutine, public calculate_rhotot_elec_gspace(qs_env, auxbas_pw_pool, rhotot_elec_gspace, q_max, rho_hard, rho_soft, fsign, compute_tau, rho_source, allow_nonorthorhombic)
The total electronic density in reciprocal space (g-space) is calculated.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
Utility routines for the memory handling.
Interface to the message passing library MPI.
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
This module defines the grid data type and some basic operations on it.
Definition pw_grids.F:36
subroutine, public get_pw_grid_info(pw_grid, id_nr, mode, vol, dvol, npts, ngpts, ngpts_cut, dr, cutoff, orthorhombic, gvectors, gsquare)
Access to information stored in the pw_grid_type.
Definition pw_grids.F:185
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
superstucture that hold various representations of the density and keeps track of which ones are vali...
All kind of helpful little routines.
Definition util.F:14
subroutine, public xray_diffraction_spectrum(qs_env, unit_number, q_max)
Calculate the coherent X-ray diffraction spectrum using the total electronic density in reciprocal sp...
Provides all information about an atomic kind.
stores all the informations relevant to an mpi environment
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
keeps the density in various representations, keeping track of which ones are valid.