(git:f2099e5)
Loading...
Searching...
No Matches
casino_utils.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!> \brief Writer for CASINO gwfn.data files.
10!> \par History
11!> 05.2026 created [Codex]
12! **************************************************************************************************
14
18 USE cell_types, ONLY: cell_type,&
19 pbc,&
22 USE cp2k_info, ONLY: cp2k_version
24 USE cp_cfm_types, ONLY: cp_cfm_to_fm
26 USE cp_dbcsr_api, ONLY: dbcsr_p_type
28 USE cp_files, ONLY: close_file,&
33 USE cp_fm_types, ONLY: cp_fm_create,&
47 USE kinds, ONLY: default_path_length,&
49 dp
55 USE kpoint_types, ONLY: get_kpoint_env,&
61 USE mathconstants, ONLY: pi,&
62 rootpi
64 USE orbital_pointers, ONLY: nso
68 USE qs_kind_types, ONLY: get_qs_kind,&
71 USE qs_mo_types, ONLY: get_mo_set,&
79#include "./base/base_uses.f90"
80
81 IMPLICIT NONE
82
83 PRIVATE
84
85 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'casino_utils'
86 INTEGER, PARAMETER, PRIVATE :: max_casino_l = 4
87
88 PUBLIC :: write_casino
89
90CONTAINS
91
92! **************************************************************************************************
93!> \brief Write a CASINO gwfn.data file from the converged GPW/GAPW wavefunction.
94!> \param qs_env the QS environment
95!> \param casino_section the DFT%PRINT%CASINO input section
96! **************************************************************************************************
97 SUBROUTINE write_casino(qs_env, casino_section)
98 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
99 TYPE(section_vals_type), INTENT(IN), POINTER :: casino_section
100
101 CHARACTER(LEN=*), PARAMETER :: routinen = 'write_casino'
102
103 CHARACTER(len=default_path_length) :: filename
104 INTEGER :: ao_num, col_offset, handle, iao, iatom, ikind, ikp, ikp_loc, ikp_out, imo, ipgf, &
105 iset, ishell, ishell_loc, ispin, iw, k, l, mo_num, nao_shell, natoms, nel_tot, &
106 ngth_pseudo, nkp, nkp_mo, nkp_out, nmo, npseudo_atoms, nreal_k, nset, nsgf, nsgp_pseudo, &
107 nspins, output_unit, periodicity, prim_num, shell_num, zatom
108 INTEGER, ALLOCATABLE, DIMENSION(:) :: agauge, ao_to_atom, atomic_number, cp2k_to_casino_ao, &
109 first_shell, kp_order, prim_per_shell, shell_ang_mom, shell_type
110 INTEGER, DIMENSION(2) :: kp_range, nmo_spin
111 INTEGER, DIMENSION(:), POINTER :: npgf, nshell
112 INTEGER, DIMENSION(:, :), POINTER :: l_shell_set
113 LOGICAL :: casino_kpoints_created, do_kpoints, &
114 ionode, periodic, use_real_wfn, &
115 write_pseudos
116 LOGICAL, ALLOCATABLE, DIMENSION(:) :: kp_real
117 REAL(kind=dp) :: cval, e_nn, eps_kpoint_real, kdotg, &
118 pseudo_tol, sval, zeff
119 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: coefficients, exponents, mo_scale, &
120 valence_charge
121 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: coord, kvec, mo_energy, mos_sgf, &
122 mos_sgf_im, shell_position
123 REAL(kind=dp), DIMENSION(3) :: r_pbc, scoord, scoord_pbc
124 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp, zetas
125 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: gcc
126 TYPE(cell_type), POINTER :: cell
127 TYPE(cp_blacs_env_type), POINTER :: blacs_env
128 TYPE(cp_fm_struct_type), POINTER :: fm_struct
129 TYPE(cp_fm_type) :: fm_dummy, fm_mo_coeff, fm_mo_coeff_im, &
130 kp_coeff_im, kp_coeff_re
131 TYPE(cp_logger_type), POINTER :: logger
132 TYPE(dft_control_type), POINTER :: dft_control
133 TYPE(gth_potential_type), POINTER :: gth_potential
134 TYPE(gto_basis_set_type), POINTER :: basis_set
135 TYPE(kpoint_env_p_type), DIMENSION(:), POINTER :: kp_env
136 TYPE(kpoint_type), POINTER :: casino_kpoints, kpoints
137 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos, mos_kp
138 TYPE(mp_para_env_type), POINTER :: para_env, para_env_inter_kp
139 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
140 TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
141 TYPE(sgp_potential_type), POINTER :: sgp_potential
142
143 CALL timeset(routinen, handle)
144
145 NULLIFY (basis_set, blacs_env, casino_kpoints, cell, dft_control, fm_struct, gcc, &
146 gth_potential, kind_set, kp_env, kpoints, l_shell_set, logger, mos, mos_kp, npgf, &
147 nshell, para_env, para_env_inter_kp, particle_set, sgp_potential, xkp, zetas)
148
149 logger => cp_get_default_logger()
150 output_unit = cp_logger_get_default_io_unit(logger)
151
152 cpassert(ASSOCIATED(qs_env))
153
154 CALL section_vals_val_get(casino_section, "FILENAME", c_val=filename)
155 IF (len_trim(filename) == 0) filename = "gwfn.data"
156 CALL section_vals_val_get(casino_section, "EPS_KPOINT_REAL", r_val=eps_kpoint_real)
157 CALL section_vals_val_get(casino_section, "WRITE_PSEUDOPOTENTIALS", l_val=write_pseudos)
158
159 CALL get_qs_env(qs_env, para_env=para_env)
160 ionode = para_env%is_source()
161
162 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set, qs_kind_set=kind_set, &
163 natom=natoms, dft_control=dft_control, nelectron_total=nel_tot, &
164 do_kpoints=do_kpoints, kpoints=kpoints, blacs_env=blacs_env)
165 casino_kpoints => kpoints
166 casino_kpoints_created = .false.
167 CALL prepare_casino_kpoint_grid(qs_env, casino_section, do_kpoints, kpoints, &
168 casino_kpoints, casino_kpoints_created)
169 nspins = dft_control%nspins
170 IF (nspins > 2) cpabort("CASINO gwfn.data supports at most two spin channels.")
171
172 periodicity = count(cell%perd /= 0)
173 periodic = periodicity > 0
174 pseudo_tol = 1.0e-8_dp
175
176 ALLOCATE (coord(3, natoms), atomic_number(natoms), valence_charge(natoms))
177 npseudo_atoms = 0
178 ngth_pseudo = 0
179 nsgp_pseudo = 0
180 DO iatom = 1, natoms
181 coord(:, iatom) = particle_set(iatom)%r(1:3)
182 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
183 CALL get_qs_kind(kind_set(ikind), zatom=zatom, zeff=zeff, &
184 gth_potential=gth_potential, sgp_potential=sgp_potential)
185 IF (abs(zeff) < pseudo_tol) zeff = real(zatom, kind=dp)
186 atomic_number(iatom) = zatom
187 IF (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) THEN
188 atomic_number(iatom) = zatom + 200
189 npseudo_atoms = npseudo_atoms + 1
190 IF (ASSOCIATED(gth_potential)) ngth_pseudo = ngth_pseudo + 1
191 IF (ASSOCIATED(sgp_potential)) nsgp_pseudo = nsgp_pseudo + 1
192 ELSE IF (abs(zeff - real(zatom, kind=dp)) > pseudo_tol) THEN
193 atomic_number(iatom) = zatom + 200
194 npseudo_atoms = npseudo_atoms + 1
195 END IF
196 valence_charge(iatom) = zeff
197 END DO
198
199 IF (ionode .AND. write_pseudos .AND. nsgp_pseudo > 0) THEN
200 CALL write_casino_sgp_pseudopotentials(kind_set, particle_set, natoms, filename, output_unit)
201 END IF
202
203 IF (periodic) THEN
204 CALL periodic_nuclear_repulsion_energy(cell, periodicity, coord, valence_charge, e_nn)
205 ELSE
206 CALL nuclear_repulsion_energy(particle_set, kind_set, e_nn)
207 END IF
208 e_nn = e_nn/real(natoms, kind=dp)
209
210 IF (do_kpoints) THEN
211 CALL get_kpoint_info(casino_kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn)
212 ELSE
213 nkp = 1
214 use_real_wfn = .true.
215 END IF
216 nkp_mo = merge(nkp, 1, do_kpoints)
217
218 ALLOCATE (kp_order(nkp_mo), kp_real(nkp_mo), kvec(3, nkp_mo))
219 CALL build_kpoint_order(cell, periodic, do_kpoints, nkp, xkp, eps_kpoint_real, &
220 kp_order, kp_real, nkp_out, nreal_k, kvec)
221 IF (do_kpoints .AND. use_real_wfn .AND. any(.NOT. kp_real(1:nkp_out))) THEN
222 cpabort("CASINO complex k-points require CP2K complex k-point wavefunctions.")
223 END IF
224
225 CALL get_qs_kind_set(kind_set, nshell=shell_num, npgf_seg=prim_num, nsgf=nsgf)
226 ao_num = nsgf
227
228 ALLOCATE (shell_type(shell_num), prim_per_shell(shell_num), first_shell(natoms + 1), &
229 shell_ang_mom(shell_num), shell_position(3, shell_num), &
230 exponents(prim_num), coefficients(prim_num), ao_to_atom(ao_num), &
231 cp2k_to_casino_ao(ao_num), mo_scale(ao_num))
232
233 ishell = 0
234 ipgf = 0
235 iao = 0
236 DO iatom = 1, natoms
237 first_shell(iatom) = ishell + 1
238 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
239 CALL get_qs_kind(kind_set(ikind), basis_set=basis_set, basis_type="ORB")
240 CALL get_gto_basis_set(basis_set, nset=nset, nshell=nshell, npgf=npgf, &
241 zet=zetas, gcc=gcc, l=l_shell_set)
242 DO iset = 1, nset
243 DO ishell_loc = 1, nshell(iset)
244 ishell = ishell + 1
245 l = l_shell_set(ishell_loc, iset)
246 IF (l > max_casino_l) THEN
247 cpabort("CASINO writer currently supports harmonic Gaussian shells up to g.")
248 END IF
249 shell_ang_mom(ishell) = l
250 shell_type(ishell) = casino_shell_type(l)
251 prim_per_shell(ishell) = npgf(iset)
252 shell_position(:, ishell) = particle_set(iatom)%r(1:3)
253 CALL casino_shell_coefficients(l, npgf(iset), zetas(1:npgf(iset), iset), &
254 gcc(1:npgf(iset), ishell_loc, iset), &
255 exponents(ipgf + 1:ipgf + npgf(iset)), &
256 coefficients(ipgf + 1:ipgf + npgf(iset)))
257 nao_shell = nso(l)
258 DO k = 1, nao_shell
259 cp2k_to_casino_ao(iao + k) = iao + casino_cp2k_index(l, k)
260 mo_scale(iao + k) = casino_mo_scale(l, k)
261 ao_to_atom(iao + k) = iatom
262 END DO
263 ipgf = ipgf + npgf(iset)
264 iao = iao + nao_shell
265 END DO
266 END DO
267 END DO
268 first_shell(natoms + 1) = shell_num + 1
269 cpassert(ishell == shell_num)
270 cpassert(ipgf == prim_num)
271 cpassert(iao == ao_num)
272
273 ALLOCATE (mo_energy(ao_num, nkp_mo*nspins))
274 mo_energy(:, :) = 0.0_dp
275 nmo_spin(:) = 0
276
277 IF (do_kpoints) THEN
278 CALL get_kpoint_info(casino_kpoints, kp_env=kp_env, kp_range=kp_range, nkp=nkp)
279 CALL get_kpoint_env(kp_env(1)%kpoint_env, mos=mos_kp)
280 DO ispin = 1, nspins
281 CALL get_mo_set(mos_kp(ispin), nmo=nmo)
282 IF (nmo < ao_num) THEN
283 cpabort("CASINO gwfn.data requires a complete MO set. Increase ADDED_MOS.")
284 END IF
285 nmo_spin(ispin) = nmo
286 END DO
287 mo_num = nkp*sum(nmo_spin)
288 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
289 nrow_global=nsgf, ncol_global=mo_num)
290 CALL cp_fm_create(fm_mo_coeff, fm_struct)
291 CALL cp_fm_set_all(fm_mo_coeff, 0.0_dp)
292 IF (.NOT. use_real_wfn) THEN
293 CALL cp_fm_create(fm_mo_coeff_im, fm_struct)
294 CALL cp_fm_set_all(fm_mo_coeff_im, 0.0_dp)
295 CALL cp_fm_create(kp_coeff_re, mos_kp(1)%cmo_coeff%matrix_struct)
296 CALL cp_fm_create(kp_coeff_im, mos_kp(1)%cmo_coeff%matrix_struct)
297 END IF
298 CALL cp_fm_struct_release(fm_struct)
299
300 DO ispin = 1, nspins
301 DO ikp = 1, nkp
302 nmo = nmo_spin(ispin)
303 col_offset = (ikp - 1)*nmo + (ispin - 1)*nmo_spin(1)*nkp
304 IF (ikp >= kp_range(1) .AND. ikp <= kp_range(2)) THEN
305 ikp_loc = ikp - kp_range(1) + 1
306 CALL get_kpoint_env(kp_env(ikp_loc)%kpoint_env, mos=mos_kp)
307 IF (use_real_wfn) THEN
308 IF (mos_kp(ispin)%use_mo_coeff_b) THEN
309 CALL copy_dbcsr_to_fm(mos_kp(ispin)%mo_coeff_b, mos_kp(ispin)%mo_coeff)
310 END IF
311 ELSE
312 CALL cp_cfm_to_fm(mos_kp(ispin)%cmo_coeff, kp_coeff_re, kp_coeff_im)
313 END IF
314 IF (use_real_wfn) THEN
315 CALL cp_fm_to_fm_submat_general(mos_kp(ispin)%mo_coeff, fm_mo_coeff, &
316 nsgf, nmo, 1, 1, 1, col_offset + 1, blacs_env)
317 ELSE
318 CALL cp_fm_to_fm_submat_general(kp_coeff_re, fm_mo_coeff, &
319 nsgf, nmo, 1, 1, 1, col_offset + 1, blacs_env)
320 END IF
321 mo_energy(1:ao_num, ikp + (ispin - 1)*nkp_mo) = &
322 mos_kp(ispin)%eigenvalues(1:ao_num)
323 IF (.NOT. use_real_wfn) THEN
324 CALL cp_fm_to_fm_submat_general(kp_coeff_im, fm_mo_coeff_im, &
325 nsgf, nmo, 1, 1, 1, col_offset + 1, blacs_env)
326 END IF
327 ELSE
328 CALL cp_fm_to_fm_submat_general(fm_dummy, fm_mo_coeff, &
329 nsgf, nmo, 1, 1, 1, col_offset + 1, blacs_env)
330 IF (.NOT. use_real_wfn) THEN
331 CALL cp_fm_to_fm_submat_general(fm_dummy, fm_mo_coeff_im, &
332 nsgf, nmo, 1, 1, 1, col_offset + 1, blacs_env)
333 END IF
334 END IF
335 END DO
336 END DO
337 CALL get_kpoint_info(casino_kpoints, para_env_inter_kp=para_env_inter_kp)
338 CALL para_env_inter_kp%sum(mo_energy)
339 ELSE
340 CALL get_qs_env(qs_env, mos=mos)
341 DO ispin = 1, nspins
342 CALL get_mo_set(mos(ispin), nmo=nmo)
343 IF (nmo < ao_num) THEN
344 cpabort("CASINO gwfn.data requires a complete MO set. Increase ADDED_MOS.")
345 END IF
346 nmo_spin(ispin) = nmo
347 mo_energy(1:ao_num, 1 + (ispin - 1)*nkp_mo) = mos(ispin)%eigenvalues(1:ao_num)
348 END DO
349 END IF
350
351 IF (do_kpoints .AND. .NOT. use_real_wfn) THEN
352 ALLOCATE (agauge(3*natoms))
353 DO iatom = 1, natoms
354 CALL real_to_scaled(scoord, particle_set(iatom)%r(1:3), cell)
355 IF (kpoints%symmetry) THEN
356 r_pbc = pbc_stable(particle_set(iatom)%r(1:3), cell)
357 ELSE
358 r_pbc = pbc(particle_set(iatom)%r(1:3), cell)
359 END IF
360 CALL real_to_scaled(scoord_pbc, r_pbc, cell)
361 agauge(3*(iatom - 1) + 1:3*iatom) = nint(scoord_pbc - scoord)
362 END DO
363 END IF
364
365 IF (ionode) THEN
366 IF (npseudo_atoms > 0) THEN
367 WRITE (output_unit, "((T2,A,I0,A))") "CASINO| Marked ", npseudo_atoms, &
368 " pseudopotential atoms in gwfn.data."
369 IF (ngth_pseudo > 0) THEN
370 WRITE (output_unit, "((T2,A))") &
371 "CASINO| GTH pseudopotentials require matching external CASINO *_pp.data files."
372 END IF
373 IF (.NOT. write_pseudos) THEN
374 WRITE (output_unit, "((T2,A))") &
375 "CASINO| WRITE_PSEUDOPOTENTIALS is disabled; provide CASINO *_pp.data files manually."
376 END IF
377 END IF
378 WRITE (output_unit, "((T2,A,A))") 'CASINO| Writing gwfn.data file ', trim(filename)
379 CALL open_file(file_name=filename, file_status="REPLACE", file_action="WRITE", &
380 file_form="FORMATTED", unit_number=iw)
381 CALL write_casino_header(iw, periodicity, nspins, e_nn, nel_tot, natoms, coord, &
382 atomic_number, valence_charge, cell, periodic, nkp_out, nreal_k, &
383 kvec, shell_num, ao_num, prim_num, shell_ang_mom, shell_type, &
384 prim_per_shell, first_shell, exponents, coefficients, shell_position)
385 END IF
386
387 ALLOCATE (mos_sgf(nsgf, ao_num), mos_sgf_im(nsgf, ao_num))
388 mos_sgf(:, :) = 0.0_dp
389 mos_sgf_im(:, :) = 0.0_dp
390
391 IF (do_kpoints) THEN
392 DO ispin = 1, nspins
393 DO ikp_out = 1, nkp_out
394 ikp = kp_order(ikp_out)
395 col_offset = (ikp - 1)*nmo_spin(ispin) + (ispin - 1)*nmo_spin(1)*nkp
396 CALL cp_fm_get_submatrix(fm_mo_coeff, mos_sgf, 1, col_offset + 1, nsgf, ao_num)
397 IF (.NOT. use_real_wfn) THEN
398 CALL cp_fm_get_submatrix(fm_mo_coeff_im, mos_sgf_im, 1, col_offset + 1, nsgf, ao_num)
399 DO iao = 1, ao_num
400 iatom = ao_to_atom(iao)
401 kdotg = 2.0_dp*pi*dot_product(xkp(:, ikp), &
402 REAL(agauge(3*(iatom - 1) + 1:3*iatom), kind=dp))
403 cval = cos(kdotg)
404 sval = sin(kdotg)
405 DO imo = 1, ao_num
406 CALL rotate_complex_pair(mos_sgf(cp2k_to_casino_ao(iao), imo), &
407 mos_sgf_im(cp2k_to_casino_ao(iao), imo), cval, sval)
408 END DO
409 END DO
410 ELSE
411 mos_sgf_im(:, :) = 0.0_dp
412 END IF
413 IF (ionode) THEN
414 CALL write_casino_orbitals(iw, mos_sgf, mos_sgf_im, cp2k_to_casino_ao, mo_scale, &
415 ao_num,.NOT. kp_real(ikp_out))
416 END IF
417 END DO
418 END DO
419 ELSE
420 DO ispin = 1, nspins
421 IF (mos(ispin)%use_mo_coeff_b) THEN
422 CALL copy_dbcsr_to_fm(mos(ispin)%mo_coeff_b, mos(ispin)%mo_coeff)
423 END IF
424 CALL cp_fm_get_submatrix(mos(ispin)%mo_coeff, mos_sgf, 1, 1, nsgf, ao_num)
425 mos_sgf_im(:, :) = 0.0_dp
426 IF (ionode) THEN
427 CALL write_casino_orbitals(iw, mos_sgf, mos_sgf_im, cp2k_to_casino_ao, mo_scale, &
428 ao_num, .false.)
429 END IF
430 END DO
431 END IF
432
433 IF (ionode) THEN
434 WRITE (iw, *)
435 IF (periodic) THEN
436 WRITE (iw, '(A)') "EIGENVALUES"
437 WRITE (iw, '(A)') "-----------"
438 DO ikp_out = 1, nkp_out
439 ikp = kp_order(ikp_out)
440 DO ispin = 1, nspins
441 IF (nspins == 1) THEN
442 WRITE (iw, '(A,I6,3F14.8)') "k", ikp_out, kvec(:, ikp_out)
443 ELSE
444 WRITE (iw, '(A,I3,A,I6,3F14.8)') "spin", ispin, " k", ikp_out, kvec(:, ikp_out)
445 END IF
446 CALL write_real_vector(iw, mo_energy(1:ao_num, ikp + (ispin - 1)*nkp_mo))
447 END DO
448 END DO
449 END IF
450 CALL close_file(unit_number=iw)
451 END IF
452
453 DEALLOCATE (mos_sgf, mos_sgf_im)
454 IF (do_kpoints) THEN
455 CALL cp_fm_release(fm_mo_coeff)
456 IF (.NOT. use_real_wfn) THEN
457 CALL cp_fm_release(fm_mo_coeff_im)
458 CALL cp_fm_release(kp_coeff_re)
459 CALL cp_fm_release(kp_coeff_im)
460 END IF
461 END IF
462 IF (casino_kpoints_created) CALL kpoint_release(casino_kpoints)
463 IF (ALLOCATED(agauge)) DEALLOCATE (agauge)
464 DEALLOCATE (ao_to_atom, atomic_number, coefficients, coord, cp2k_to_casino_ao, exponents, &
465 first_shell, kp_order, kp_real, kvec, mo_energy, mo_scale, prim_per_shell, &
466 shell_ang_mom, shell_position, shell_type, valence_charge)
467
468 CALL timestop(handle)
469 END SUBROUTINE write_casino
470
471! **************************************************************************************************
472!> \brief Write CASINO pseudopotential files for the semilocal ECP kinds.
473!> \param kind_set the QS kinds
474!> \param particle_set the particle set
475!> \param natoms the number of atoms
476!> \param gwfn_filename the gwfn.data filename
477!> \param output_unit output unit for log messages
478! **************************************************************************************************
479 SUBROUTINE write_casino_sgp_pseudopotentials(kind_set, particle_set, natoms, gwfn_filename, output_unit)
480 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
481 POINTER :: kind_set
482 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
483 POINTER :: particle_set
484 INTEGER, INTENT(IN) :: natoms
485 CHARACTER(LEN=*), INTENT(IN) :: gwfn_filename
486 INTEGER, INTENT(IN) :: output_unit
487
488 CHARACTER(LEN=2) :: element_symbol
489 INTEGER :: iatom, ikind, zatom
490 LOGICAL, ALLOCATABLE, DIMENSION(:) :: written
491 REAL(kind=dp) :: zeff
492 TYPE(sgp_potential_type), POINTER :: sgp_potential
493
494 NULLIFY (sgp_potential)
495 ALLOCATE (written(SIZE(kind_set)))
496 written(:) = .false.
497
498 DO iatom = 1, natoms
499 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, element_symbol=element_symbol, &
500 kind_number=ikind, z=zatom)
501 IF (written(ikind)) cycle
502
503 CALL get_qs_kind(kind_set(ikind), sgp_potential=sgp_potential, zeff=zeff)
504 IF (ASSOCIATED(sgp_potential)) THEN
505 IF (abs(zeff) < 1.0e-8_dp) zeff = real(zatom, kind=dp)
506 CALL write_casino_sgp_pseudopotential(sgp_potential, element_symbol, zatom, zeff, &
507 gwfn_filename, output_unit)
508 written(ikind) = .true.
509 END IF
510 END DO
511
512 DEALLOCATE (written)
513 END SUBROUTINE write_casino_sgp_pseudopotentials
514
515! **************************************************************************************************
516!> \brief Write a CASINO tabulated pseudopotential for a CP2K semilocal ECP.
517!> \param sgp_potential the CP2K semilocal Gaussian potential
518!> \param element_symbol the chemical symbol
519!> \param zatom the nuclear charge
520!> \param zeff the ECP valence charge
521!> \param gwfn_filename the gwfn.data filename
522!> \param output_unit output unit for log messages
523! **************************************************************************************************
524 SUBROUTINE write_casino_sgp_pseudopotential(sgp_potential, element_symbol, zatom, zeff, &
525 gwfn_filename, output_unit)
526 TYPE(sgp_potential_type), INTENT(IN), POINTER :: sgp_potential
527 CHARACTER(LEN=*), INTENT(IN) :: element_symbol
528 INTEGER, INTENT(IN) :: zatom
529 REAL(kind=dp), INTENT(IN) :: zeff
530 CHARACTER(LEN=*), INTENT(IN) :: gwfn_filename
531 INTEGER, INTENT(IN) :: output_unit
532
533 CHARACTER(LEN=default_path_length) :: pp_filename
534 INTEGER :: igrid, iw, l, local_l, ngrid, nloc, &
535 nsemiloc, sl_lmax
536 INTEGER, DIMENSION(0:10) :: npot
537 LOGICAL :: ecp_local, ecp_semi_local, has_nlcc
538 REAL(kind=dp) :: agrid, bgrid, r, rmax, rv_local
539 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: rgrid
540 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: rpot
541
542 CALL get_potential(potential=sgp_potential, ecp_local=ecp_local, &
543 ecp_semi_local=ecp_semi_local, nloc=nloc, sl_lmax=sl_lmax, &
544 npot=npot, has_nlcc=has_nlcc)
545 IF (.NOT. ecp_local .OR. nloc == 0) THEN
546 WRITE (output_unit, "((T2,A,A,A))") "CASINO| Cannot write ", trim(element_symbol), &
547 "_pp.data: only CP2K semilocal ECP potentials are supported."
548 RETURN
549 END IF
550
551 local_l = merge(sl_lmax + 1, 0, ecp_semi_local)
552 rmax = 100.0_dp
553 agrid = 70.0_dp*exp(-5.0_dp*log(10.0_dp))/real(zatom, kind=dp)
554 bgrid = 1.0_dp/70.0_dp
555
556 ngrid = 0
557 DO
558 r = agrid*(exp(bgrid*real(ngrid, kind=dp)) - 1.0_dp)
559 IF (r > rmax) EXIT
560 ngrid = ngrid + 1
561 END DO
562
563 ALLOCATE (rgrid(ngrid), rpot(0:local_l, ngrid))
564 DO igrid = 1, ngrid
565 r = agrid*(exp(bgrid*real(igrid - 1, kind=dp)) - 1.0_dp)
566 rgrid(igrid) = r
567 rv_local = casino_sgp_r_times_v(nloc, sgp_potential%nrloc(1:nloc), &
568 sgp_potential%bloc(1:nloc), &
569 sgp_potential%aloc(1:nloc), r, zeff, .true.)
570 DO l = 0, local_l
571 rpot(l, igrid) = rv_local
572 IF (l < local_l .AND. ecp_semi_local) THEN
573 nsemiloc = npot(l)
574 IF (nsemiloc > 0) THEN
575 rpot(l, igrid) = rpot(l, igrid) + &
576 casino_sgp_r_times_v(nsemiloc, sgp_potential%nrpot(1:nsemiloc, l), &
577 sgp_potential%bpot(1:nsemiloc, l), &
578 sgp_potential%apot(1:nsemiloc, l), r, zeff, .false.)
579 END IF
580 END IF
581 END DO
582 END DO
583 rpot(:, :) = 2.0_dp*rpot(:, :)
584
585 CALL casino_pp_filename(gwfn_filename, element_symbol, pp_filename)
586 CALL open_file(file_name=pp_filename, file_status="REPLACE", file_action="WRITE", &
587 file_form="FORMATTED", unit_number=iw)
588 WRITE (iw, '(A)') "CP2K ECP pseudopotential in real space"
589 WRITE (iw, '(A)') "Atomic number and pseudo-charge"
590 WRITE (iw, '(I6,1X,F18.10)') zatom, zeff
591 WRITE (iw, '(A)') "Energy units (rydberg/hartree/ev):"
592 WRITE (iw, '(A)') "rydberg"
593 WRITE (iw, '(A)') "Angular momentum of local component (0=s,1=p,2=d..)"
594 WRITE (iw, '(I6)') local_l
595 WRITE (iw, '(A)') "NLRULE override (1) VMC/DMC (2) config gen (0 ==> input/default value)"
596 WRITE (iw, '(2I6)') 0, 0
597 WRITE (iw, '(A)') "Number of grid points"
598 WRITE (iw, '(I8)') ngrid
599 WRITE (iw, '(A)') "R(i) in atomic units"
600 DO igrid = 1, ngrid
601 WRITE (iw, '(ES20.12)') rgrid(igrid)
602 END DO
603 DO l = 0, local_l
604 WRITE (iw, '(A,I0,A)') "r*potential (L=", l, ") in Ry"
605 DO igrid = 1, ngrid
606 WRITE (iw, '(ES20.12)') rpot(l, igrid)
607 END DO
608 END DO
609 CALL close_file(unit_number=iw)
610
611 WRITE (output_unit, "((T2,A,A))") "CASINO| Wrote pseudopotential file ", trim(pp_filename)
612 IF (has_nlcc) THEN
613 WRITE (output_unit, "((T2,A,A,A))") "CASINO| NLCC terms for ", trim(element_symbol), &
614 " are not represented in CASINO *_pp.data."
615 END IF
616
617 DEALLOCATE (rgrid, rpot)
618 END SUBROUTINE write_casino_sgp_pseudopotential
619
620! **************************************************************************************************
621!> \brief Return r times a CP2K semilocal Gaussian ECP channel in Hartree.
622!> \param nterm the number of Gaussian terms
623!> \param nr the CP2K r**(n-2) exponents
624!> \param gaussian_exponent the Gaussian exponents
625!> \param coefficient the Gaussian coefficients
626!> \param r the radial grid point
627!> \param zeff the ECP valence charge
628!> \param local_channel true for the local Coulomb-tailed channel
629!> \return r times the potential value
630! **************************************************************************************************
631 FUNCTION casino_sgp_r_times_v(nterm, nr, gaussian_exponent, coefficient, r, zeff, local_channel) RESULT(r_times_v)
632 INTEGER, INTENT(IN) :: nterm
633 INTEGER, DIMENSION(:), INTENT(IN) :: nr
634 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: gaussian_exponent, coefficient
635 REAL(kind=dp), INTENT(IN) :: r, zeff
636 LOGICAL, INTENT(IN) :: local_channel
637 REAL(kind=dp) :: r_times_v
638
639 INTEGER :: iterm
640
641 IF (r == 0.0_dp) THEN
642 r_times_v = 0.0_dp
643 RETURN
644 END IF
645
646 r_times_v = 0.0_dp
647 IF (local_channel) r_times_v = -zeff
648 DO iterm = 1, nterm
649 cpassert(nr(iterm) >= 1)
650 r_times_v = r_times_v + coefficient(iterm)*r**(nr(iterm) - 1)* &
651 exp(-gaussian_exponent(iterm)*r*r)
652 END DO
653 END FUNCTION casino_sgp_r_times_v
654
655! **************************************************************************************************
656!> \brief Build the CASINO pseudopotential filename next to gwfn.data.
657!> \param gwfn_filename the gwfn.data filename
658!> \param element_symbol the chemical symbol
659!> \param pp_filename the CASINO pseudopotential filename
660! **************************************************************************************************
661 SUBROUTINE casino_pp_filename(gwfn_filename, element_symbol, pp_filename)
662 CHARACTER(LEN=*), INTENT(IN) :: gwfn_filename, element_symbol
663 CHARACTER(LEN=*), INTENT(OUT) :: pp_filename
664
665 CHARACTER(LEN=2) :: symbol
666 INTEGER :: slash
667
668 symbol = adjustl(element_symbol)
669 CALL lowercase(symbol)
670 slash = index(trim(gwfn_filename), "/", back=.true.)
671 IF (slash > 0) THEN
672 pp_filename = gwfn_filename(1:slash)//trim(symbol)//"_pp.data"
673 ELSE
674 pp_filename = trim(symbol)//"_pp.data"
675 END IF
676 END SUBROUTINE casino_pp_filename
677
678! **************************************************************************************************
679!> \brief Prepare the k-point object used for CASINO export.
680!> \param qs_env the QS environment
681!> \param casino_section the CASINO print section
682!> \param do_kpoints true when the SCF used k-points
683!> \param kpoints_scf the converged SCF k-point object
684!> \param kpoints_out the k-point object to write
685!> \param created true if kpoints_out must be released by the caller
686! **************************************************************************************************
687 SUBROUTINE prepare_casino_kpoint_grid(qs_env, casino_section, do_kpoints, kpoints_scf, &
688 kpoints_out, created)
689 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
690 TYPE(section_vals_type), INTENT(IN), POINTER :: casino_section
691 LOGICAL, INTENT(IN) :: do_kpoints
692 TYPE(kpoint_type), POINTER :: kpoints_scf, kpoints_out
693 LOGICAL, INTENT(OUT) :: created
694
695 CHARACTER(LEN=*), PARAMETER :: routinen = 'prepare_casino_kpoint_grid'
696
697 CHARACTER(LEN=default_string_length) :: kp_scheme, reuse_reason
698 INTEGER :: aligned_blocks, aligned_max_size, &
699 handle, nfull, output_unit
700 INTEGER, DIMENSION(3) :: nkp_grid
701 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
702 LOGICAL :: diis_step, full_grid, full_kpoint_grid, &
703 gamma_centered, reuse_scf_mos, &
704 reused_scf_mos, symmetry
705 REAL(kind=dp) :: aligned_min_svalue, eps_geo, wsum
706 REAL(kind=dp), DIMENSION(3) :: kp_shift
707 REAL(kind=dp), DIMENSION(:), POINTER :: wkp_source
708 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp_source
709 TYPE(cell_type), POINTER :: cell
710 TYPE(cp_blacs_env_type), POINTER :: blacs_env
711 TYPE(cp_logger_type), POINTER :: logger
712 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
713 TYPE(dft_control_type), POINTER :: dft_control
714 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
715 TYPE(mp_para_env_type), POINTER :: para_env
716 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
717 POINTER :: sab_nl
718 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
719 TYPE(qs_scf_env_type), POINTER :: scf_env
720 TYPE(scf_control_type), POINTER :: scf_control
721
722 CALL timeset(routinen, handle)
723
724 created = .false.
725 kpoints_out => kpoints_scf
726 NULLIFY (blacs_env, cell, cell_to_index, dft_control, logger, matrix_ks, matrix_s, mos, &
727 para_env, particle_set, sab_nl, scf_control, scf_env, wkp_source, xkp_source)
728
729 IF (.NOT. do_kpoints) THEN
730 CALL timestop(handle)
731 RETURN
732 END IF
733 cpassert(ASSOCIATED(kpoints_scf))
734
735 CALL get_kpoint_info(kpoints_scf, kp_scheme=kp_scheme, symmetry=symmetry, &
736 full_grid=full_grid, nkp_grid=nkp_grid, kp_shift=kp_shift, &
737 gamma_centered=gamma_centered, eps_geo=eps_geo)
738 IF (.NOT. symmetry .OR. full_grid) THEN
739 CALL timestop(handle)
740 RETURN
741 END IF
742
743 CALL section_vals_val_get(casino_section, "FULL_KPOINT_GRID", l_val=full_kpoint_grid)
744 IF (.NOT. full_kpoint_grid) THEN
745 cpabort("CASINO export requires a full k-point grid. Use PRINT%CASINO%FULL_KPOINT_GRID.")
746 END IF
747
748 SELECT CASE (trim(kp_scheme))
749 CASE ("MONKHORST-PACK", "MACDONALD", "GENERAL")
750 ! supported below
751 CASE DEFAULT
752 cpabort("CASINO%FULL_KPOINT_GRID supports only MONKHORST-PACK, MACDONALD, and GENERAL k-points.")
753 END SELECT
754
755 logger => cp_get_default_logger()
756 output_unit = cp_logger_get_default_io_unit(logger)
757 CALL section_vals_val_get(casino_section, "REUSE_SCF_MOS", l_val=reuse_scf_mos)
758 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell, &
759 particle_set=particle_set, mos=mos, dft_control=dft_control, &
760 sab_orb=sab_nl, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s, &
761 scf_env=scf_env, scf_control=scf_control)
762 cpassert(ASSOCIATED(para_env))
763 cpassert(ASSOCIATED(blacs_env))
764 cpassert(ASSOCIATED(cell))
765 cpassert(ASSOCIATED(particle_set))
766 cpassert(ASSOCIATED(mos))
767 cpassert(ASSOCIATED(dft_control))
768 cpassert(ASSOCIATED(sab_nl))
769 cpassert(ASSOCIATED(matrix_ks))
770 cpassert(ASSOCIATED(matrix_s))
771 cpassert(ASSOCIATED(scf_env))
772 cpassert(ASSOCIATED(scf_control))
773
774 NULLIFY (kpoints_out)
775 CALL kpoint_create(kpoints_out)
776 kpoints_out%kp_scheme = kp_scheme
777 kpoints_out%symmetry = .false.
778 kpoints_out%full_grid = .true.
779 kpoints_out%verbose = .false.
780 kpoints_out%use_real_wfn = .false.
781 kpoints_out%eps_geo = eps_geo
782 kpoints_out%parallel_group_size = para_env%num_pe
783
784 SELECT CASE (trim(kp_scheme))
785 CASE ("MONKHORST-PACK", "MACDONALD")
786 kpoints_out%nkp_grid(1:3) = nkp_grid(1:3)
787 kpoints_out%kp_shift(1:3) = kp_shift(1:3)
788 kpoints_out%gamma_centered = gamma_centered
789 CALL kpoint_initialize(kpoints_out, particle_set, cell)
790 CASE ("GENERAL")
791 IF (.NOT. ASSOCIATED(kpoints_scf%xkp_input) .OR. &
792 .NOT. ASSOCIATED(kpoints_scf%wkp_input)) THEN
793 cpabort("CASINO%FULL_KPOINT_GRID cannot recover the unreduced GENERAL k-point set.")
794 END IF
795 xkp_source => kpoints_scf%xkp_input
796 wkp_source => kpoints_scf%wkp_input
797 nfull = SIZE(wkp_source)
798 wsum = sum(wkp_source)
799 IF (wsum <= 0.0_dp) cpabort("CASINO%FULL_KPOINT_GRID found invalid GENERAL k-point weights.")
800 kpoints_out%nkp = nfull
801 ALLOCATE (kpoints_out%xkp(3, nfull), kpoints_out%wkp(nfull))
802 kpoints_out%xkp(1:3, 1:nfull) = xkp_source(1:3, 1:nfull)
803 kpoints_out%wkp(1:nfull) = wkp_source(1:nfull)/wsum
804 END SELECT
805
806 CALL kpoint_env_initialize(kpoints_out, para_env, blacs_env)
807 CALL kpoint_initialize_mos(kpoints_out, mos)
808 CALL kpoint_initialize_mo_set(kpoints_out)
809 CALL kpoint_init_cell_index(kpoints_out, sab_nl, para_env, dft_control%nimages)
810
811 reused_scf_mos = .false.
812 reuse_reason = ""
813 aligned_blocks = 0
814 aligned_max_size = 0
815 aligned_min_svalue = 0.0_dp
816 diis_step = .false.
817 IF (reuse_scf_mos) THEN
818 CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints_scf, scf_env, scf_control, .false., &
819 diis_step)
820 CALL get_kpoint_info(kpoints_out, cell_to_index=cell_to_index)
821 CALL prepare_wannier90_scf_mos(kpoints_out, kpoints_scf, matrix_s, matrix_ks, &
822 cell_to_index, sab_nl, para_env, reused_scf_mos, &
823 reuse_reason, aligned_blocks, aligned_max_size, &
824 aligned_min_svalue)
825 END IF
826 IF (reused_scf_mos) THEN
827 IF (output_unit > 0) THEN
828 WRITE (output_unit, '(T2,A)') &
829 "CASINO| Reused SCF MO coefficients for the full k-point grid."
830 IF (aligned_blocks > 0) THEN
831 WRITE (output_unit, '(T2,A,I0,A,I0,A,ES10.3)') &
832 "CASINO| Ritz-stabilized ", aligned_blocks, &
833 " degenerate SCF MO subspace(s); largest block has ", aligned_max_size, &
834 " band(s), min metric eigenvalue ", aligned_min_svalue
835 END IF
836 END IF
837 ELSE
838 IF (output_unit > 0) THEN
839 IF (reuse_scf_mos) THEN
840 WRITE (output_unit, '(T2,A,A)') &
841 "CASINO| Could not reuse SCF MOs: ", trim(reuse_reason)
842 END IF
843 WRITE (output_unit, '(T2,A)') &
844 "CASINO| Diagonalizing the full k-point grid for export."
845 END IF
846 diis_step = .false.
847 CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints_out, scf_env, scf_control, .false., &
848 diis_step)
849 END IF
850 created = .true.
851
852 CALL timestop(handle)
853 END SUBROUTINE prepare_casino_kpoint_grid
854
855! **************************************************************************************************
856!> \brief Build the CASINO k-point order with all real k-points first.
857!> \param cell ...
858!> \param periodic ...
859!> \param do_kpoints ...
860!> \param nkp_total ...
861!> \param xkp ...
862!> \param eps_kpoint_real ...
863!> \param kp_order ...
864!> \param kp_real ...
865!> \param nkp_out ...
866!> \param nreal_k ...
867!> \param kvec ...
868! **************************************************************************************************
869 SUBROUTINE build_kpoint_order(cell, periodic, do_kpoints, nkp_total, xkp, eps_kpoint_real, &
870 kp_order, kp_real, nkp_out, nreal_k, kvec)
871 TYPE(cell_type), INTENT(IN), POINTER :: cell
872 LOGICAL, INTENT(IN) :: periodic, do_kpoints
873 INTEGER, INTENT(IN) :: nkp_total
874 REAL(kind=dp), DIMENSION(:, :), INTENT(IN), &
875 OPTIONAL, POINTER :: xkp
876 REAL(kind=dp), INTENT(IN) :: eps_kpoint_real
877 INTEGER, DIMENSION(:), INTENT(OUT) :: kp_order
878 LOGICAL, DIMENSION(:), INTENT(OUT) :: kp_real
879 INTEGER, INTENT(OUT) :: nkp_out, nreal_k
880 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: kvec
881
882 INTEGER :: ikp, jkp, ncomplex_k
883 INTEGER, DIMENSION(nkp_total) :: complex_order, real_order
884 LOGICAL, DIMENSION(nkp_total) :: used
885
886 IF (.NOT. periodic) THEN
887 kp_order(1) = 1
888 kp_real(1) = .true.
889 nkp_out = 1
890 nreal_k = 1
891 kvec(:, 1) = 0.0_dp
892 RETURN
893 END IF
894
895 IF (.NOT. do_kpoints) THEN
896 kp_order(1) = 1
897 kp_real(1) = .true.
898 nkp_out = 1
899 nreal_k = 1
900 kvec(:, 1) = 0.0_dp
901 RETURN
902 END IF
903
904 used(:) = .false.
905 nreal_k = 0
906 ncomplex_k = 0
907
908 DO ikp = 1, nkp_total
909 IF (is_real_kpoint(cell, xkp(:, ikp), eps_kpoint_real)) THEN
910 used(ikp) = .true.
911 nreal_k = nreal_k + 1
912 real_order(nreal_k) = ikp
913 END IF
914 END DO
915
916 DO ikp = 1, nkp_total
917 IF (.NOT. used(ikp)) THEN
918 used(ikp) = .true.
919 ncomplex_k = ncomplex_k + 1
920 complex_order(ncomplex_k) = ikp
921 DO jkp = ikp + 1, nkp_total
922 IF (.NOT. used(jkp)) THEN
923 IF (is_conjugate_kpoint(cell, xkp(:, ikp), xkp(:, jkp), eps_kpoint_real)) THEN
924 used(jkp) = .true.
925 EXIT
926 END IF
927 END IF
928 END DO
929 END IF
930 END DO
931
932 nkp_out = nreal_k + ncomplex_k
933 DO ikp = 1, nreal_k
934 kp_order(ikp) = real_order(ikp)
935 kp_real(ikp) = .true.
936 kvec(:, ikp) = 2.0_dp*pi*matmul(transpose(cell%h_inv), xkp(:, real_order(ikp)))
937 END DO
938 DO ikp = 1, ncomplex_k
939 jkp = nreal_k + ikp
940 kp_order(jkp) = complex_order(ikp)
941 kp_real(jkp) = .false.
942 kvec(:, jkp) = 2.0_dp*pi*matmul(transpose(cell%h_inv), xkp(:, complex_order(ikp)))
943 END DO
944 END SUBROUTINE build_kpoint_order
945
946! **************************************************************************************************
947!> \brief Returns true for conjugate k-points modulo reciprocal lattice vectors.
948!> \param cell ...
949!> \param xk1 ...
950!> \param xk2 ...
951!> \param eps_kpoint_real ...
952!> \return ...
953! **************************************************************************************************
954 FUNCTION is_conjugate_kpoint(cell, xk1, xk2, eps_kpoint_real) RESULT(is_conjugate)
955 TYPE(cell_type), INTENT(IN), POINTER :: cell
956 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xk1, xk2
957 REAL(kind=dp), INTENT(IN) :: eps_kpoint_real
958 LOGICAL :: is_conjugate
959
960 INTEGER :: idir
961 REAL(kind=dp) :: reduced
962
963 is_conjugate = .true.
964 DO idir = 1, 3
965 IF (cell%perd(idir) /= 0) THEN
966 reduced = xk1(idir) + xk2(idir)
967 reduced = reduced - real(nint(reduced), kind=dp)
968 IF (abs(reduced) > eps_kpoint_real) THEN
969 is_conjugate = .false.
970 EXIT
971 END IF
972 END IF
973 END DO
974 END FUNCTION is_conjugate_kpoint
975
976! **************************************************************************************************
977!> \brief Returns true for Gamma/BZ-edge k-points where real Bloch orbitals can be used.
978!> \param cell ...
979!> \param xk ...
980!> \param eps_kpoint_real ...
981!> \return ...
982! **************************************************************************************************
983 FUNCTION is_real_kpoint(cell, xk, eps_kpoint_real) RESULT(is_real)
984 TYPE(cell_type), INTENT(IN), POINTER :: cell
985 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xk
986 REAL(kind=dp), INTENT(IN) :: eps_kpoint_real
987 LOGICAL :: is_real
988
989 INTEGER :: idir
990 REAL(kind=dp) :: reduced
991
992 is_real = .true.
993 DO idir = 1, 3
994 IF (cell%perd(idir) /= 0) THEN
995 reduced = xk(idir) - real(nint(xk(idir)), kind=dp)
996 IF (abs(reduced) > eps_kpoint_real .AND. &
997 abs(abs(reduced) - 0.5_dp) > eps_kpoint_real) is_real = .false.
998 END IF
999 END DO
1000 END FUNCTION is_real_kpoint
1001
1002! **************************************************************************************************
1003!> \brief Write all non-orbital CASINO gwfn.data sections.
1004!> \param iw ...
1005!> \param periodicity ...
1006!> \param nspins ...
1007!> \param e_nn ...
1008!> \param nel_tot ...
1009!> \param natoms ...
1010!> \param coord ...
1011!> \param atomic_number ...
1012!> \param valence_charge ...
1013!> \param cell ...
1014!> \param periodic ...
1015!> \param nkp ...
1016!> \param nreal_k ...
1017!> \param kvec ...
1018!> \param shell_num ...
1019!> \param ao_num ...
1020!> \param prim_num ...
1021!> \param shell_ang_mom ...
1022!> \param shell_type ...
1023!> \param prim_per_shell ...
1024!> \param first_shell ...
1025!> \param exponents ...
1026!> \param coefficients ...
1027!> \param shell_position ...
1028! **************************************************************************************************
1029 SUBROUTINE write_casino_header(iw, periodicity, nspins, e_nn, nel_tot, natoms, coord, &
1030 atomic_number, valence_charge, cell, periodic, nkp, nreal_k, kvec, &
1031 shell_num, ao_num, prim_num, shell_ang_mom, shell_type, prim_per_shell, &
1032 first_shell, exponents, coefficients, shell_position)
1033 INTEGER, INTENT(IN) :: iw, periodicity, nspins
1034 REAL(kind=dp), INTENT(IN) :: e_nn
1035 INTEGER, INTENT(IN) :: nel_tot, natoms
1036 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: coord
1037 INTEGER, DIMENSION(:), INTENT(IN) :: atomic_number
1038 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: valence_charge
1039 TYPE(cell_type), INTENT(IN), POINTER :: cell
1040 LOGICAL, INTENT(IN) :: periodic
1041 INTEGER, INTENT(IN) :: nkp, nreal_k
1042 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: kvec
1043 INTEGER, INTENT(IN) :: shell_num, ao_num, prim_num
1044 INTEGER, DIMENSION(:), INTENT(IN) :: shell_ang_mom, shell_type, &
1045 prim_per_shell, first_shell
1046 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: exponents, coefficients
1047 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: shell_position
1048
1049 INTEGER :: highest_ang_mom, i
1050
1051 highest_ang_mom = maxval(shell_ang_mom) + 1
1052
1053 WRITE (iw, '(A)') "CP2K CASINO gwfn.data"
1054 WRITE (iw, *)
1055 WRITE (iw, '(A)') "BASIC INFO"
1056 WRITE (iw, '(A)') "----------"
1057 WRITE (iw, '(A)') "Generated by:"
1058 WRITE (iw, '(1X,A)') trim(cp2k_version)
1059 WRITE (iw, '(A)') "Method:"
1060 WRITE (iw, '(A)') " DFT"
1061 WRITE (iw, '(A)') "DFT functional:"
1062 WRITE (iw, '(A)') " CP2K"
1063 WRITE (iw, '(A)') "Periodicity:"
1064 WRITE (iw, '(1X,I0)') periodicity
1065 WRITE (iw, '(A)') "Spin unrestricted:"
1066 WRITE (iw, '(1X,A)') merge(".true. ", ".false.", nspins > 1)
1067 WRITE (iw, '(A)') "Nuclear repulsion energy (au/atom):"
1068 WRITE (iw, '(1PE20.13)') e_nn
1069 WRITE (iw, '(A)') "Number of electrons per primitive cell"
1070 WRITE (iw, '(1X,I0)') nel_tot
1071 WRITE (iw, *)
1072
1073 WRITE (iw, '(A)') "GEOMETRY"
1074 WRITE (iw, '(A)') "--------"
1075 WRITE (iw, '(A)') "Number of atoms"
1076 WRITE (iw, '(1X,I0)') natoms
1077 WRITE (iw, '(A)') "Atomic positions (au)"
1078 DO i = 1, natoms
1079 WRITE (iw, '(3(1PE20.13))') coord(:, i)
1080 END DO
1081 WRITE (iw, '(A)') "Atomic numbers for each atom"
1082 CALL write_integer_vector(iw, atomic_number)
1083 WRITE (iw, '(A)') "Valence charges for each atom"
1084 CALL write_real_vector(iw, valence_charge)
1085 IF (.NOT. periodic) WRITE (iw, *)
1086 IF (periodic) THEN
1087 WRITE (iw, '(A)') "Primitive lattice vectors (au)"
1088 DO i = 1, 3
1089 WRITE (iw, '(3(1PE20.13))') cell%hmat(:, i)
1090 END DO
1091 WRITE (iw, *)
1092
1093 WRITE (iw, '(A)') "K SPACE NET"
1094 WRITE (iw, '(A)') "-----------"
1095 WRITE (iw, '(A)') "Number of k points"
1096 WRITE (iw, '(1X,I0)') nkp
1097 WRITE (iw, '(A)') "Number of 'real' k points on BZ edge"
1098 WRITE (iw, '(1X,I0)') nreal_k
1099 WRITE (iw, '(A)') "k point coordinates (au)"
1100 DO i = 1, nkp
1101 WRITE (iw, '(3(1PE20.13))') kvec(:, i)
1102 END DO
1103 WRITE (iw, *)
1104 END IF
1105
1106 WRITE (iw, '(A)') "BASIS SET"
1107 WRITE (iw, '(A)') "---------"
1108 WRITE (iw, '(A)') "Number of Gaussian centres"
1109 WRITE (iw, '(1X,I0)') natoms
1110 WRITE (iw, '(A)') "Number of shells per primitive cell"
1111 WRITE (iw, '(1X,I0)') shell_num
1112 WRITE (iw, '(A)') "Number of basis functions ('AO') per primitive cell"
1113 WRITE (iw, '(1X,I0)') ao_num
1114 WRITE (iw, '(A)') "Number of Gaussian primitives per primitive cell"
1115 WRITE (iw, '(1X,I0)') prim_num
1116 WRITE (iw, '(A)') "Highest shell angular momentum (s/p/d/f/g... 1/2/3/4/5...)"
1117 WRITE (iw, '(1X,I0)') highest_ang_mom
1118 WRITE (iw, '(A)') "Code for shell types (s/sp/p/d/f... 1/2/3/4/5...)"
1119 CALL write_integer_vector(iw, shell_type)
1120 WRITE (iw, '(A)') "Number of primitive Gaussians in each shell"
1121 CALL write_integer_vector(iw, prim_per_shell)
1122 WRITE (iw, '(A)') "Sequence number of first shell on each centre"
1123 CALL write_integer_vector(iw, first_shell)
1124 WRITE (iw, '(A)') "Exponents of Gaussian primitives"
1125 CALL write_real_vector(iw, exponents)
1126 WRITE (iw, '(A)') "Correctly normalised contraction coefficients"
1127 CALL write_real_vector(iw, coefficients)
1128 WRITE (iw, '(A)') "Position of each shell (au)"
1129 DO i = 1, shell_num
1130 WRITE (iw, '(3(1PE20.13))') shell_position(:, i)
1131 END DO
1132 WRITE (iw, *)
1133
1134 WRITE (iw, '(A)') "MULTIDETERMINANT INFORMATION"
1135 WRITE (iw, '(A)') "----------------------------"
1136 WRITE (iw, '(A)') "GS"
1137 WRITE (iw, *)
1138 WRITE (iw, '(A)') "ORBITAL COEFFICIENTS"
1139 WRITE (iw, '(A)') "---------------------------"
1140 END SUBROUTINE write_casino_header
1141
1142! **************************************************************************************************
1143!> \brief Write one CASINO MO block for a spin/k-point.
1144!> \param iw ...
1145!> \param mos_sgf ...
1146!> \param mos_sgf_im ...
1147!> \param cp2k_to_casino_ao ...
1148!> \param mo_scale ...
1149!> \param ao_num ...
1150!> \param complex_orbitals ...
1151! **************************************************************************************************
1152 SUBROUTINE write_casino_orbitals(iw, mos_sgf, mos_sgf_im, cp2k_to_casino_ao, mo_scale, ao_num, &
1153 complex_orbitals)
1154 INTEGER, INTENT(IN) :: iw
1155 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: mos_sgf, mos_sgf_im
1156 INTEGER, DIMENSION(:), INTENT(IN) :: cp2k_to_casino_ao
1157 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: mo_scale
1158 INTEGER, INTENT(IN) :: ao_num
1159 LOGICAL, INTENT(IN) :: complex_orbitals
1160
1161 INTEGER :: iao, imo, nbuffer
1162 REAL(kind=dp), DIMENSION(4) :: buffer
1163
1164 nbuffer = 0
1165 buffer(:) = 0.0_dp
1166 DO imo = 1, ao_num
1167 DO iao = 1, ao_num
1168 CALL push_real(iw, buffer, nbuffer, mo_scale(iao)*mos_sgf(cp2k_to_casino_ao(iao), imo))
1169 IF (complex_orbitals) THEN
1170 CALL push_real(iw, buffer, nbuffer, mo_scale(iao)*mos_sgf_im(cp2k_to_casino_ao(iao), imo))
1171 END IF
1172 END DO
1173 END DO
1174 IF (nbuffer > 0) WRITE (iw, '(4(1PE20.13))') buffer(1:nbuffer)
1175 END SUBROUTINE write_casino_orbitals
1176
1177! **************************************************************************************************
1178!> \brief Append one real number to a four-column output buffer.
1179!> \param iw ...
1180!> \param buffer ...
1181!> \param nbuffer ...
1182!> \param value ...
1183! **************************************************************************************************
1184 SUBROUTINE push_real(iw, buffer, nbuffer, value)
1185 INTEGER, INTENT(IN) :: iw
1186 REAL(kind=dp), DIMENSION(4), INTENT(INOUT) :: buffer
1187 INTEGER, INTENT(INOUT) :: nbuffer
1188 REAL(kind=dp), INTENT(IN) :: value
1189
1190 nbuffer = nbuffer + 1
1191 buffer(nbuffer) = value
1192 IF (nbuffer == SIZE(buffer)) THEN
1193 WRITE (iw, '(4(1PE20.13))') buffer
1194 nbuffer = 0
1195 END IF
1196 END SUBROUTINE push_real
1197
1198! **************************************************************************************************
1199!> \brief Write an integer vector in CASINO-friendly fixed-width columns.
1200!> \param iw ...
1201!> \param values ...
1202! **************************************************************************************************
1203 SUBROUTINE write_integer_vector(iw, values)
1204 INTEGER, INTENT(IN) :: iw
1205 INTEGER, DIMENSION(:), INTENT(IN) :: values
1206
1207 INTEGER :: i, ilast
1208
1209 DO i = 1, SIZE(values), 8
1210 ilast = min(i + 7, SIZE(values))
1211 WRITE (iw, '(8I10)') values(i:ilast)
1212 END DO
1213 END SUBROUTINE write_integer_vector
1214
1215! **************************************************************************************************
1216!> \brief Write a real vector in CASINO-friendly fixed-width columns.
1217!> \param iw ...
1218!> \param values ...
1219! **************************************************************************************************
1220 SUBROUTINE write_real_vector(iw, values)
1221 INTEGER, INTENT(IN) :: iw
1222 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: values
1223
1224 INTEGER :: i, ilast
1225
1226 DO i = 1, SIZE(values), 4
1227 ilast = min(i + 3, SIZE(values))
1228 WRITE (iw, '(4(1PE20.13))') values(i:ilast)
1229 END DO
1230 END SUBROUTINE write_real_vector
1231
1232! **************************************************************************************************
1233!> \brief Rotate a complex value by exp(-i*k.g) using the TREXIO gauge convention.
1234!> \param re ...
1235!> \param im ...
1236!> \param cval ...
1237!> \param sval ...
1238! **************************************************************************************************
1239 SUBROUTINE rotate_complex_pair(re, im, cval, sval)
1240 REAL(kind=dp), INTENT(INOUT) :: re, im
1241 REAL(kind=dp), INTENT(IN) :: cval, sval
1242
1243 REAL(kind=dp) :: im_old, re_old
1244
1245 re_old = re
1246 im_old = im
1247 re = cval*re_old + sval*im_old
1248 im = -sval*re_old + cval*im_old
1249 END SUBROUTINE rotate_complex_pair
1250
1251! **************************************************************************************************
1252!> \brief Convert CP2K normalized primitive data to CASINO contraction coefficients.
1253!> \param l ...
1254!> \param nprim ...
1255!> \param zetas ...
1256!> \param gcc ...
1257!> \param exponents ...
1258!> \param coefficients ...
1259! **************************************************************************************************
1260 SUBROUTINE casino_shell_coefficients(l, nprim, zetas, gcc, exponents, coefficients)
1261 INTEGER, INTENT(IN) :: l, nprim
1262 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: zetas, gcc
1263 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: exponents, coefficients
1264
1265 INTEGER :: i
1266 REAL(kind=dp) :: contraction_norm, expzet, prefac, &
1267 prim_cart_fac
1268 REAL(kind=dp), DIMENSION(nprim) :: raw_coeff
1269
1270 expzet = 0.25_dp*real(2*l + 3, kind=dp)
1271 prefac = 2.0_dp**l*(2.0_dp/pi)**0.75_dp
1272 DO i = 1, nprim
1273 prim_cart_fac = prefac*zetas(i)**expzet
1274 raw_coeff(i) = gcc(i)/prim_cart_fac
1275 END DO
1276 contraction_norm = casino_contraction_norm(l, nprim, zetas, raw_coeff)
1277 DO i = 1, nprim
1278 exponents(i) = zetas(i)
1279 coefficients(i) = raw_coeff(i)*contraction_norm*casino_primitive_norm(l, zetas(i))
1280 END DO
1281 END SUBROUTINE casino_shell_coefficients
1282
1283! **************************************************************************************************
1284!> \brief Whole-contraction normalization used by CASINO's molden2qmc converter.
1285!> \param l ...
1286!> \param nprim ...
1287!> \param zetas ...
1288!> \param raw_coeff ...
1289!> \return ...
1290! **************************************************************************************************
1291 FUNCTION casino_contraction_norm(l, nprim, zetas, raw_coeff) RESULT(norm)
1292 INTEGER, INTENT(IN) :: l, nprim
1293 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: zetas, raw_coeff
1294 REAL(kind=dp) :: norm
1295
1296 INTEGER :: i, j
1297 REAL(kind=dp) :: overlap
1298
1299 overlap = 0.0_dp
1300 DO i = 1, nprim
1301 DO j = 1, nprim
1302 overlap = overlap + raw_coeff(i)*raw_coeff(j)* &
1303 (2.0_dp*sqrt(zetas(i)*zetas(j))/(zetas(i) + zetas(j)))**(l + 1.5_dp)
1304 END DO
1305 END DO
1306 norm = 1.0_dp/sqrt(overlap)
1307 END FUNCTION casino_contraction_norm
1308
1309! **************************************************************************************************
1310!> \brief Primitive m-independent normalization used by CASINO's Gaussian evaluator.
1311!> \param l ...
1312!> \param alpha ...
1313!> \return ...
1314! **************************************************************************************************
1315 FUNCTION casino_primitive_norm(l, alpha) RESULT(norm)
1316 INTEGER, INTENT(IN) :: l
1317 REAL(kind=dp), INTENT(IN) :: alpha
1318 REAL(kind=dp) :: norm
1319
1320 norm = sqrt(2.0_dp**(l + 1.5_dp)*alpha**(l + 1.5_dp))/pi**0.75_dp
1321 IF (l > 0) norm = norm*sqrt(2.0_dp**l/odd_double_factorial(2*l - 1))
1322 END FUNCTION casino_primitive_norm
1323
1324! **************************************************************************************************
1325!> \brief CASINO shell type code.
1326!> \param l ...
1327!> \return ...
1328! **************************************************************************************************
1329 FUNCTION casino_shell_type(l) RESULT(shell_type)
1330 INTEGER, INTENT(IN) :: l
1331 INTEGER :: shell_type
1332
1333 IF (l == 0) THEN
1334 shell_type = 1
1335 ELSE
1336 shell_type = l + 2
1337 END IF
1338 END FUNCTION casino_shell_type
1339
1340! **************************************************************************************************
1341!> \brief CP2K AO index for a CASINO/MOLDEN ordered harmonic shell.
1342!> \param l ...
1343!> \param k ...
1344!> \return ...
1345! **************************************************************************************************
1346 FUNCTION casino_cp2k_index(l, k) RESULT(idx)
1347 INTEGER, INTENT(IN) :: l, k
1348 INTEGER :: idx
1349
1350 INTEGER, DIMENSION(9, 0:max_casino_l), PARAMETER :: map = reshape([1, 0, 0, 0, 0, 0, 0, 0, 0 &
1351 , 3, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 2, 5, 1, 0, 0, 0, 0, 4, 5, 3, 6, 2, 7, 1, 0, 0, 5, 6, 4&
1352 , 7, 3, 8, 2, 9, 1], [9, max_casino_l + 1])
1353
1354 idx = map(k, l)
1355 END FUNCTION casino_cp2k_index
1356
1357! **************************************************************************************************
1358!> \brief Scale factors converting MOLDEN harmonic MO coefficients to CASINO conventions.
1359!> \param l ...
1360!> \param k ...
1361!> \return ...
1362! **************************************************************************************************
1363 FUNCTION casino_mo_scale(l, k) RESULT(scale)
1364 INTEGER, INTENT(IN) :: l, k
1365 REAL(kind=dp) :: scale
1366
1367 REAL(kind=dp), DIMENSION(5), PARAMETER :: d_factor = [0.5_dp, 3.0_dp, 3.0_dp, 3.0_dp, 6.0_dp]
1368
1369 INTEGER :: m
1370
1371 IF (l <= 1) THEN
1372 scale = 1.0_dp
1373 ELSE
1374 m = casino_m_quantum_number(k)
1375 scale = casino_m_dependent_factor(l, m)
1376 IF (l == 2) scale = scale*d_factor(k)
1377 END IF
1378 END FUNCTION casino_mo_scale
1379
1380! **************************************************************************************************
1381!> \brief m sequence in CASINO/MOLDEN harmonic order: 0,+1,-1,+2,-2,...
1382!> \param k ...
1383!> \return ...
1384! **************************************************************************************************
1385 FUNCTION casino_m_quantum_number(k) RESULT(m)
1386 INTEGER, INTENT(IN) :: k
1387 INTEGER :: m
1388
1389 IF (k == 1) THEN
1390 m = 0
1391 ELSE IF (mod(k, 2) == 0) THEN
1392 m = k/2
1393 ELSE
1394 m = -(k/2)
1395 END IF
1396 END FUNCTION casino_m_quantum_number
1397
1398! **************************************************************************************************
1399!> \brief CASINO m-dependent normalization factor.
1400!> \param l ...
1401!> \param m ...
1402!> \return ...
1403! **************************************************************************************************
1404 FUNCTION casino_m_dependent_factor(l, m) RESULT(factor)
1405 INTEGER, INTENT(IN) :: l, m
1406 REAL(kind=dp) :: factor
1407
1408 INTEGER :: am
1409 REAL(kind=dp) :: prefactor
1410
1411 am = abs(m)
1412 prefactor = merge(1.0_dp, 2.0_dp, am == 0)
1413 factor = sqrt(prefactor*factorial(l - am)/factorial(l + am))
1414 END FUNCTION casino_m_dependent_factor
1415
1416! **************************************************************************************************
1417!> \brief Real factorial for small non-negative integers.
1418!> \param n ...
1419!> \return ...
1420! **************************************************************************************************
1421 FUNCTION factorial(n) RESULT(value)
1422 INTEGER, INTENT(IN) :: n
1423 REAL(kind=dp) :: value
1424
1425 INTEGER :: i
1426
1427 value = 1.0_dp
1428 DO i = 2, n
1429 value = value*real(i, kind=dp)
1430 END DO
1431 END FUNCTION factorial
1432
1433! **************************************************************************************************
1434!> \brief Odd double factorial.
1435!> \param n ...
1436!> \return ...
1437! **************************************************************************************************
1438 FUNCTION odd_double_factorial(n) RESULT(value)
1439 INTEGER, INTENT(IN) :: n
1440 REAL(kind=dp) :: value
1441
1442 INTEGER :: i
1443
1444 value = 1.0_dp
1445 DO i = max(1, n), 1, -2
1446 value = value*real(i, kind=dp)
1447 END DO
1448 END FUNCTION odd_double_factorial
1449
1450! **************************************************************************************************
1451!> \brief Computes the nuclear repulsion energy of a molecular system.
1452!> \param particle_set ...
1453!> \param kind_set ...
1454!> \param e_nn ...
1455! **************************************************************************************************
1456 SUBROUTINE nuclear_repulsion_energy(particle_set, kind_set, e_nn)
1457 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
1458 POINTER :: particle_set
1459 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
1460 POINTER :: kind_set
1461 REAL(kind=dp), INTENT(OUT) :: e_nn
1462
1463 INTEGER :: i, ikind, j, jkind, natoms
1464 REAL(kind=dp) :: r_ij, zeff_i, zeff_j
1465
1466 natoms = SIZE(particle_set)
1467 e_nn = 0.0_dp
1468 DO i = 1, natoms
1469 CALL get_atomic_kind(particle_set(i)%atomic_kind, kind_number=ikind)
1470 CALL get_qs_kind(kind_set(ikind), zeff=zeff_i)
1471 DO j = i + 1, natoms
1472 r_ij = norm2(particle_set(i)%r - particle_set(j)%r)
1473 CALL get_atomic_kind(particle_set(j)%atomic_kind, kind_number=jkind)
1474 CALL get_qs_kind(kind_set(jkind), zeff=zeff_j)
1475 e_nn = e_nn + zeff_i*zeff_j/r_ij
1476 END DO
1477 END DO
1478 END SUBROUTINE nuclear_repulsion_energy
1479
1480! **************************************************************************************************
1481!> \brief Computes the CASINO-compatible 3D periodic nuclear repulsion energy.
1482!> \param cell ...
1483!> \param periodicity ...
1484!> \param coord ...
1485!> \param charge ...
1486!> \param e_nn ...
1487! **************************************************************************************************
1488 SUBROUTINE periodic_nuclear_repulsion_energy(cell, periodicity, coord, charge, e_nn)
1489 TYPE(cell_type), INTENT(IN), POINTER :: cell
1490 INTEGER, INTENT(IN) :: periodicity
1491 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: coord
1492 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charge
1493 REAL(kind=dp), INTENT(OUT) :: e_nn
1494
1495 INTEGER :: gmax, i, ig1, ig2, ig3, j, n1, n2, n3, &
1496 natoms, nmax
1497 REAL(kind=dp) :: alpha, alpha2, cutoff_arg, g_cut, g_sq, min_g, min_h, neut_energy, phase, &
1498 r, real_cut, real_energy, recip_energy, self_energy, struc_im, struc_re, volume
1499 REAL(kind=dp), DIMENSION(3) :: delta, g_index, gvec, lattice_shift
1500
1501 e_nn = 0.0_dp
1502 IF (periodicity /= 3) RETURN
1503
1504 volume = abs(cell%deth)
1505 IF (volume <= 0.0_dp) cpabort("CASINO periodic nuclear repulsion requires a non-zero cell volume.")
1506
1507 natoms = SIZE(charge)
1508 IF (natoms == 0) RETURN
1509
1510 min_h = huge(1.0_dp)
1511 min_g = huge(1.0_dp)
1512 DO i = 1, 3
1513 min_h = min(min_h, norm2(cell%hmat(:, i)))
1514 g_index = 0.0_dp
1515 g_index(i) = 1.0_dp
1516 gvec = 2.0_dp*pi*matmul(transpose(cell%h_inv), g_index)
1517 min_g = min(min_g, norm2(gvec))
1518 END DO
1519 IF (min_h <= 0.0_dp .OR. min_g <= 0.0_dp) THEN
1520 cpabort("CASINO periodic nuclear repulsion requires non-zero lattice vectors.")
1521 END IF
1522
1523 cutoff_arg = sqrt(-log(1.0e-12_dp))
1524 alpha = rootpi*(real(natoms, kind=dp)/volume)**(1.0_dp/3.0_dp)
1525 alpha2 = alpha*alpha
1526 real_cut = cutoff_arg/alpha
1527 g_cut = 2.0_dp*alpha*cutoff_arg
1528 nmax = max(1, ceiling(real_cut/min_h) + 1)
1529 gmax = max(1, ceiling(g_cut/min_g) + 1)
1530
1531 real_energy = 0.0_dp
1532 DO i = 1, natoms
1533 DO j = 1, natoms
1534 DO n1 = -nmax, nmax
1535 DO n2 = -nmax, nmax
1536 DO n3 = -nmax, nmax
1537 IF (i == j .AND. n1 == 0 .AND. n2 == 0 .AND. n3 == 0) cycle
1538 lattice_shift = real(n1, kind=dp)*cell%hmat(:, 1) + &
1539 REAL(n2, kind=dp)*cell%hmat(:, 2) + &
1540 REAL(n3, kind=dp)*cell%hmat(:, 3)
1541 delta = coord(:, i) - coord(:, j) + lattice_shift
1542 r = norm2(delta)
1543 IF (r <= real_cut) real_energy = real_energy + charge(i)*charge(j)*erfc(alpha*r)/r
1544 END DO
1545 END DO
1546 END DO
1547 END DO
1548 END DO
1549 real_energy = 0.5_dp*real_energy
1550
1551 recip_energy = 0.0_dp
1552 DO ig1 = -gmax, gmax
1553 DO ig2 = -gmax, gmax
1554 DO ig3 = -gmax, gmax
1555 IF (ig1 == 0 .AND. ig2 == 0 .AND. ig3 == 0) cycle
1556 g_index = [real(ig1, kind=dp), real(ig2, kind=dp), real(ig3, kind=dp)]
1557 gvec = 2.0_dp*pi*matmul(transpose(cell%h_inv), g_index)
1558 g_sq = dot_product(gvec, gvec)
1559 IF (sqrt(g_sq) > g_cut) cycle
1560 struc_re = 0.0_dp
1561 struc_im = 0.0_dp
1562 DO i = 1, natoms
1563 phase = dot_product(gvec, coord(:, i))
1564 struc_re = struc_re + charge(i)*cos(phase)
1565 struc_im = struc_im + charge(i)*sin(phase)
1566 END DO
1567 recip_energy = recip_energy + exp(-g_sq/(4.0_dp*alpha2))/g_sq* &
1568 (struc_re*struc_re + struc_im*struc_im)
1569 END DO
1570 END DO
1571 END DO
1572 recip_energy = 2.0_dp*pi*recip_energy/volume
1573
1574 self_energy = -alpha*sum(charge*charge)/rootpi
1575 neut_energy = -pi*sum(charge)**2/(2.0_dp*alpha2*volume)
1576 e_nn = real_energy + recip_energy + self_energy + neut_energy
1577 END SUBROUTINE periodic_nuclear_repulsion_energy
1578
1579END MODULE casino_utils
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
Writer for CASINO gwfn.data files.
subroutine, public write_casino(qs_env, casino_section)
Write a CASINO gwfn.data file from the converged GPW/GAPW wavefunction.
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition cell_types.F:595
real(kind=dp) function, dimension(3), public pbc_stable(r, cell)
Apply a stable periodic-image convention for k-point Bloch gauges.
Definition cell_types.F:422
some minimal info about CP2K, including its version and license
Definition cp2k_info.F:22
character(len= *), parameter, public cp2k_version
Definition cp2k_info.F:50
methods related to the blacs parallel environment
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan)
Copy a DBCSR matrix to a BLACS matrix.
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:323
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:123
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_to_fm_submat_general(source, destination, nrows, ncols, s_firstrow, s_firstcol, d_firstrow, d_firstcol, global_context)
General copy of a submatrix of fm matrix to a submatrix of another fm matrix. The two matrices can ha...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Definition of the atomic potential types.
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Routines needed for kpoint calculation.
subroutine, public kpoint_initialize_mo_set(kpoint)
...
subroutine, public kpoint_init_cell_index(kpoint, sab_nl, para_env, nimages)
Generates the mapping of cell indices and linear RS index CELL (0,0,0) is always mapped to index 1.
subroutine, public kpoint_initialize_mos(kpoint, mos, added_mos, for_aux_fit)
Initialize a set of MOs and density matrix for each kpoint (kpoint group).
subroutine, public kpoint_initialize(kpoint, particle_set, cell)
Generate the kpoints and initialize the kpoint environment.
subroutine, public kpoint_env_initialize(kpoint, para_env, blacs_env, with_aux_fit)
Initialize the kpoint environment.
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_env(kpoint_env, nkpoint, wkp, xkp, is_local, mos)
Get information from a single kpoint environment.
subroutine, public kpoint_release(kpoint)
Release a kpoint environment, deallocate all data.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
subroutine, public kpoint_create(kpoint)
Create a kpoint environment.
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public rootpi
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nso
Define the data structure for the particle information.
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.
Define the quickstep kind type and their sub types.
logical function, public has_nlcc(qs_kind_set)
finds if a given qs run needs to use nlcc
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, do_mtlr_present, basis_type, total_zeff_corr, npgf_seg, cneo_potential_present, nkind_q, natom_q)
Get attributes of an atomic kind set.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count, cmo_coeff)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
Different diagonalization schemes that can be used for the iterative solution of the eigenvalue probl...
subroutine, public do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, diis_step, diis_error, qs_env, probe, added_mos_auto_grow, potential)
Kpoint diagonalization routine Transforms matrices to kpoint, distributes kpoint groups,...
module that contains the definitions of the scf types
Interface to Wannier90 code.
subroutine, public prepare_wannier90_scf_mos(kpoint, qs_kpoint, matrix_s, matrix_ks, cell_to_index, sab_nl, para_env, success, reason, aligned_degenerate_blocks, aligned_degenerate_max_size, aligned_degenerate_min_svalue)
Reconstruct a full Wannier90 k-point MO set from the SCF k-point MOs.
parameters that control an scf iteration
Utilities for string manipulations.
elemental subroutine, public lowercase(string)
Convert all upper case characters in a string to lower case.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.