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