(git:50ddb19)
Loading...
Searching...
No Matches
trexio_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 The module to read/write TREX IO files for interfacing CP2K with other programs
10!> \par History
11!> 05.2024 created [SB]
12!> 05.2026 improved [KN]
13!> \author Stefano Battaglia
14!> \author Kosuke Nakano
15! **************************************************************************************************
17
18 USE ai_onecenter, ONLY: sg_overlap
22 USE cp2k_info, ONLY: cp2k_version
39 dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
40 dbcsr_type_symmetric, dbcsr_get_matrix_type
47 USE kinds, ONLY: default_path_length, dp
48 USE kpoint_types, ONLY: kpoint_type
49 USE mathconstants, ONLY: fourpi, pi, fac
50 USE mathlib, ONLY: symmetrize_matrix
52 USE orbital_pointers, ONLY: nco, nso
61#ifdef __TREXIO
73 USE trexio, ONLY: trexio_open, trexio_close, &
74 trexio_hdf5, trexio_success, &
75 trexio_string_of_error, trexio_t, trexio_exit_code, &
76 trexio_write_metadata_code, trexio_write_metadata_code_num, &
77 trexio_write_nucleus_coord, trexio_read_nucleus_coord, &
78 trexio_write_nucleus_num, trexio_read_nucleus_num, &
79 trexio_write_nucleus_charge, trexio_read_nucleus_charge, &
80 trexio_write_nucleus_label, trexio_read_nucleus_label, &
81 trexio_write_nucleus_repulsion, &
82 trexio_write_cell_a, trexio_write_cell_b, trexio_write_cell_c, &
83 trexio_write_cell_g_a, trexio_write_cell_g_b, &
84 trexio_write_cell_g_c, trexio_write_cell_two_pi, &
85 trexio_write_pbc_periodic, trexio_write_pbc_k_point_num, &
86 trexio_write_pbc_k_point, trexio_write_pbc_k_point_weight, &
87 trexio_write_electron_num, trexio_read_electron_num, &
88 trexio_write_electron_up_num, trexio_read_electron_up_num, &
89 trexio_write_electron_dn_num, trexio_read_electron_dn_num, &
90 trexio_write_state_num, trexio_write_state_id, &
91 trexio_write_state_energy, &
92 trexio_write_basis_type, trexio_write_basis_prim_num, &
93 trexio_write_basis_shell_num, trexio_read_basis_shell_num, &
94 trexio_write_basis_nucleus_index, &
95 trexio_write_basis_shell_ang_mom, trexio_read_basis_shell_ang_mom, &
96 trexio_write_basis_shell_factor, &
97 trexio_write_basis_r_power, trexio_write_basis_shell_index, &
98 trexio_write_basis_exponent, trexio_write_basis_coefficient, &
99 trexio_write_basis_prim_factor, &
100 trexio_write_ecp_z_core, trexio_write_ecp_max_ang_mom_plus_1, &
101 trexio_write_ecp_num, trexio_write_ecp_ang_mom, &
102 trexio_write_ecp_nucleus_index, trexio_write_ecp_exponent, &
103 trexio_write_ecp_coefficient, trexio_write_ecp_power, &
104 trexio_write_ao_cartesian, trexio_write_ao_num, &
105 trexio_read_ao_cartesian, trexio_read_ao_num, &
106 trexio_write_ao_shell, trexio_write_ao_normalization, &
107 trexio_read_ao_shell, trexio_read_ao_normalization, &
108 trexio_write_mo_num, trexio_write_mo_energy, &
109 trexio_read_mo_num, trexio_read_mo_energy, &
110 trexio_write_mo_occupation, trexio_write_mo_spin, &
111 trexio_read_mo_occupation, trexio_read_mo_spin, &
112 trexio_write_mo_class, trexio_write_mo_coefficient, &
113 trexio_read_mo_class, trexio_read_mo_coefficient, &
114 trexio_write_mo_coefficient_im, trexio_write_mo_k_point, &
115 trexio_write_mo_type
116#endif
117#include "./base/base_uses.f90"
118
119 IMPLICIT NONE
120
121 PRIVATE
122
123 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'trexio_utils'
124
125 PUBLIC :: write_trexio, read_trexio
126
127CONTAINS
128
129! **************************************************************************************************
130!> \brief Write a trexio file
131!> \param qs_env the qs environment with all the info of the computation
132!> \param trexio_section the section with the trexio info
133!> \param energy_derivative ...
134! **************************************************************************************************
135 SUBROUTINE write_trexio(qs_env, trexio_section, energy_derivative)
136 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
137 TYPE(section_vals_type), INTENT(IN), POINTER :: trexio_section
138 TYPE(dbcsr_p_type), INTENT(IN), DIMENSION(:), POINTER, OPTIONAL :: energy_derivative
139
140#ifdef __TREXIO
141 CHARACTER(LEN=*), PARAMETER :: routinen = 'write_trexio'
142
143 INTEGER :: handle, output_unit, unit_trexio
144 CHARACTER(len=default_path_length) :: filename, filename_de
145 INTEGER(trexio_t) :: f ! The TREXIO file handle
146 INTEGER(trexio_exit_code) :: rc ! TREXIO return code
147 LOGICAL :: explicit, do_kpoints, ecp_semi_local, &
148 ecp_local, sgp_potential_present, ionode, &
149 use_real_wfn, save_cartesian, &
150 trexio_kpoints_created
151 REAL(kind=dp) :: e_nn, zeff, expzet, prefac, zeta, gcca, &
152 prim_cart_fac, nsgto
153 TYPE(cell_type), POINTER :: cell
154 TYPE(cp_logger_type), POINTER :: logger
155 TYPE(dft_control_type), POINTER :: dft_control
156 TYPE(gto_basis_set_type), POINTER :: basis_set
157 TYPE(kpoint_type), POINTER :: kpoints, trexio_kpoints
158 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
159 TYPE(qs_energy_type), POINTER :: energy
160 TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
161 TYPE(sgp_potential_type), POINTER :: sgp_potential
162 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
163 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: mos_kp
164 TYPE(kpoint_env_p_type), DIMENSION(:), POINTER :: kp_env
165 TYPE(mp_para_env_type), POINTER :: para_env, para_env_inter_kp
166 TYPE(cp_blacs_env_type), POINTER :: blacs_env
167 TYPE(cp_fm_struct_type), POINTER :: fm_struct
168 TYPE(cp_fm_type) :: fm_mo_coeff, fm_dummy, fm_mo_coeff_im
169 TYPE(dbcsr_iterator_type) :: iter
170
171 CHARACTER(LEN=2) :: element_symbol
172 CHARACTER(LEN=2), DIMENSION(:), ALLOCATABLE :: label
173 INTEGER :: iatom, natoms, periodic, nkp, nel_tot, &
174 nspins, ikind, ishell_loc, ishell, &
175 shell_num, prim_num, nset, iset, ipgf, z, &
176 sl_lmax, ecp_num, nloc, nsemiloc, sl_l, iecp, &
177 iao, icgf_atom, ncgf, nao_shell, ao_num, nmo, &
178 mo_num, ispin, ikp, imo, ikp_loc, nsgf, ncgf_atom, &
179 i, j, k, l, m, unit_de, &
180 row, col, row_size, col_size, &
181 row_offset, col_offset
182 INTEGER, DIMENSION(2) :: nel_spin, kp_range, nmo_spin
183 INTEGER, DIMENSION(0:10) :: npot
184 INTEGER, DIMENSION(:), ALLOCATABLE :: nucleus_index, shell_ang_mom, r_power, &
185 shell_index, z_core, max_ang_mom_plus_1, &
186 ang_mom, powers, ao_shell, mo_spin, mo_kpoint, &
187 cp2k_to_trexio_ang_mom, ao_to_atom
188 ! Per-atom Bloch-gauge correction:
189 ! CP2K's k-space matrix builder (rskp_transform) Bloch-sums real-space blocks with
190 ! lattice vectors R supplied by the neighbour list. The neighbour list, in turn,
191 ! wraps interatomic vectors through subsys/cell_types.F :: pbc or, for symmetry reduction,
192 ! pbc_stable. Hence the effective
193 ! per-atom gauge is the image shift between the raw and wrapped coordinates, as used by
194 ! kpoint_methods.F :: kpoint_initialize. Derive it through the matching wrapper instead of
195 ! duplicating its boundary convention. Since nucleus_coord is written as the raw particle_set(i)%r, we
196 ! rephase each atom's MO block by
197 ! exp(-i 2*pi * k * agauge_i) so the (coord, MO) pair is self-consistent in the
198 ! standard Bloch convention used by TREXIO consumers.
199 INTEGER, DIMENSION(:, :), ALLOCATABLE :: agauge
200 REAL(kind=dp) :: scoord(3), scoord_pbc(3), r_pbc(3), &
201 kdotg, cval, sval, re_old, im_old
202 INTEGER, DIMENSION(:), POINTER :: nshell, npgf
203 INTEGER, DIMENSION(:, :), POINTER :: l_shell_set
204 REAL(kind=dp), DIMENSION(:), ALLOCATABLE :: charge, shell_factor, exponents, coefficients, &
205 prim_factor, ao_normalization, mo_energy, &
206 mo_occupation, sgcc, ecp_coefficients, &
207 sgf_coefficients
208 REAL(kind=dp), DIMENSION(:), POINTER :: wkp, norm_cgf
209 REAL(kind=dp), DIMENSION(:, :), ALLOCATABLE :: coord, mo_coefficient, mo_coefficient_im, &
210 mos_sgf, dedp, sloc
211 REAL(kind=dp), DIMENSION(:, :), POINTER :: zetas, data_block, xkp
212 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: gcc
213
214 CALL timeset(routinen, handle)
215
216 NULLIFY (cell, logger, dft_control, basis_set, kpoints, trexio_kpoints, particle_set, &
217 energy, kind_set)
218 NULLIFY (sgp_potential, mos, mos_kp, kp_env, para_env, para_env_inter_kp, blacs_env)
219 NULLIFY (fm_struct, nshell, npgf, l_shell_set, wkp, norm_cgf, zetas, data_block, gcc)
220
221 logger => cp_get_default_logger()
222 output_unit = cp_logger_get_default_io_unit(logger)
223
224 cpassert(ASSOCIATED(qs_env))
225
226 ! get filename
227 CALL section_vals_val_get(trexio_section, "FILENAME", c_val=filename, explicit=explicit)
228 IF (.NOT. explicit) THEN
229 filename = trim(logger%iter_info%project_name)//'-TREXIO.h5'
230 ELSE
231 filename = trim(filename)//'.h5'
232 END IF
233
234 CALL get_qs_env(qs_env, para_env=para_env)
235 ionode = para_env%is_source()
236 CALL get_qs_env(qs_env, do_kpoints=do_kpoints, kpoints=kpoints)
237 trexio_kpoints => kpoints
238 trexio_kpoints_created = .false.
239 CALL prepare_trexio_kpoint_grid(qs_env, trexio_section, do_kpoints, kpoints, &
240 trexio_kpoints, trexio_kpoints_created)
241
242 ! inquire whether a file with the same name already exists, if yes, delete it
243 IF (ionode) THEN
244 IF (file_exists(filename)) THEN
245 CALL open_file(filename, unit_number=unit_trexio)
246 CALL close_file(unit_number=unit_trexio, file_status="DELETE")
247 END IF
248
249 !========================================================================================!
250 ! Open the TREXIO file
251 !========================================================================================!
252 WRITE (output_unit, "((T2,A,A))") 'TREXIO| Writing trexio file ', trim(filename)
253 f = trexio_open(filename, 'w', trexio_hdf5, rc)
254 CALL trexio_error(rc)
255
256 !========================================================================================!
257 ! Metadata group
258 !========================================================================================!
259 rc = trexio_write_metadata_code_num(f, 1)
260 CALL trexio_error(rc)
261
262 rc = trexio_write_metadata_code(f, cp2k_version, len_trim(cp2k_version) + 1)
263 CALL trexio_error(rc)
264
265 !========================================================================================!
266 ! Nucleus group
267 !========================================================================================!
268 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set, qs_kind_set=kind_set, natom=natoms)
269
270 rc = trexio_write_nucleus_num(f, natoms)
271 CALL trexio_error(rc)
272
273 ALLOCATE (coord(3, natoms))
274 ALLOCATE (label(natoms))
275 ALLOCATE (charge(natoms))
276 DO iatom = 1, natoms
277 ! store the coordinates
278 coord(:, iatom) = particle_set(iatom)%r(1:3)
279 ! figure out the element symbol and to which kind_set entry this atomic_kind corresponds to
280 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, element_symbol=element_symbol, kind_number=ikind)
281 ! store the element symbol
282 label(iatom) = element_symbol
283 ! get and store the effective nuclear charge of this kind_type (ikind)
284 CALL get_qs_kind(kind_set(ikind), zeff=zeff)
285 charge(iatom) = zeff
286 END DO
287
288 rc = trexio_write_nucleus_coord(f, coord)
289 CALL trexio_error(rc)
290 DEALLOCATE (coord)
291
292 rc = trexio_write_nucleus_charge(f, charge)
293 CALL trexio_error(rc)
294 DEALLOCATE (charge)
295
296 rc = trexio_write_nucleus_label(f, label, 3)
297 CALL trexio_error(rc)
298 DEALLOCATE (label)
299
300 ! nuclear repulsion energy well-defined for molecules only
301 IF (sum(cell%perd) == 0) THEN
302 CALL nuclear_repulsion_energy(particle_set, kind_set, e_nn)
303 rc = trexio_write_nucleus_repulsion(f, e_nn)
304 CALL trexio_error(rc)
305 END IF
306
307 !========================================================================================!
308 ! Cell group
309 !========================================================================================!
310 rc = trexio_write_cell_a(f, cell%hmat(:, 1))
311 CALL trexio_error(rc)
312
313 rc = trexio_write_cell_b(f, cell%hmat(:, 2))
314 CALL trexio_error(rc)
315
316 rc = trexio_write_cell_c(f, cell%hmat(:, 3))
317 CALL trexio_error(rc)
318
319 rc = trexio_write_cell_g_a(f, cell%h_inv(:, 1))
320 CALL trexio_error(rc)
321
322 rc = trexio_write_cell_g_b(f, cell%h_inv(:, 2))
323 CALL trexio_error(rc)
324
325 rc = trexio_write_cell_g_c(f, cell%h_inv(:, 3))
326 CALL trexio_error(rc)
327
328 rc = trexio_write_cell_two_pi(f, 0)
329 CALL trexio_error(rc)
330
331 !========================================================================================!
332 ! PBC group
333 !========================================================================================!
334 periodic = 0
335 IF (sum(cell%perd) /= 0) periodic = 1
336 rc = trexio_write_pbc_periodic(f, periodic)
337 CALL trexio_error(rc)
338
339 IF (do_kpoints) THEN
340 CALL get_kpoint_info(trexio_kpoints, nkp=nkp, xkp=xkp, wkp=wkp)
341
342 rc = trexio_write_pbc_k_point_num(f, nkp)
343 CALL trexio_error(rc)
344
345 rc = trexio_write_pbc_k_point(f, xkp)
346 CALL trexio_error(rc)
347
348 rc = trexio_write_pbc_k_point_weight(f, wkp)
349 CALL trexio_error(rc)
350 END IF
351
352 !========================================================================================!
353 ! Electron group
354 !========================================================================================!
355 CALL get_qs_env(qs_env, dft_control=dft_control, nelectron_total=nel_tot)
356
357 rc = trexio_write_electron_num(f, nel_tot)
358 CALL trexio_error(rc)
359
360 nspins = dft_control%nspins
361 IF (nspins == 1) THEN
362 ! it is a spin-restricted calculation and we need to split the electrons manually,
363 ! because in CP2K they are all otherwise weirdly stored in nelectron_spin(1)
364 nel_spin(1) = nel_tot/2
365 nel_spin(2) = nel_tot/2
366 ELSE
367 ! for UKS/ROKS, the two spin channels are populated correctly and according to
368 ! the multiplicity
369 CALL get_qs_env(qs_env, nelectron_spin=nel_spin)
370 END IF
371 rc = trexio_write_electron_up_num(f, nel_spin(1))
372 CALL trexio_error(rc)
373 rc = trexio_write_electron_dn_num(f, nel_spin(2))
374 CALL trexio_error(rc)
375
376 !========================================================================================!
377 ! State group
378 !========================================================================================!
379 CALL get_qs_env(qs_env, energy=energy)
380
381 rc = trexio_write_state_num(f, 1)
382 CALL trexio_error(rc)
383
384 rc = trexio_write_state_id(f, 1)
385 CALL trexio_error(rc)
386
387 ! rc = trexio_write_state_energy(f, energy%total)
388 CALL trexio_error(rc)
389
390 END IF ! ionode
391
392 !========================================================================================!
393 ! Basis group
394 !========================================================================================!
395 CALL get_qs_env(qs_env, qs_kind_set=kind_set, natom=natoms, particle_set=particle_set)
396 CALL get_qs_kind_set(kind_set, nshell=shell_num, npgf_seg=prim_num)
397
398 CALL section_vals_val_get(trexio_section, "CARTESIAN", l_val=save_cartesian)
399
400 IF (ionode) THEN
401 rc = trexio_write_basis_type(f, 'Gaussian', len_trim('Gaussian') + 1)
402 CALL trexio_error(rc)
403
404 rc = trexio_write_basis_shell_num(f, shell_num)
405 CALL trexio_error(rc)
406
407 rc = trexio_write_basis_prim_num(f, prim_num)
408 CALL trexio_error(rc)
409 END IF ! ionode
410
411 ! one-to-one mapping between shells and ...
412 ALLOCATE (nucleus_index(shell_num)) ! ...atomic indices
413 ALLOCATE (shell_ang_mom(shell_num)) ! ...angular momenta
414 ALLOCATE (shell_index(prim_num)) ! ...indices of primitive functions
415 ALLOCATE (exponents(prim_num)) ! ...primitive exponents
416 ALLOCATE (coefficients(prim_num)) ! ...contraction coefficients
417 ALLOCATE (prim_factor(prim_num)) ! ...primitive normalization factors
418
419 ! needed in AO group
420 IF (.NOT. save_cartesian) THEN
421 ALLOCATE (sgf_coefficients(prim_num)) ! ...contraction coefficients
422 END IF
423
424 ishell = 0 ! global shell index
425 ipgf = 0 ! global primitives index
426 DO iatom = 1, natoms
427 ! get the qs_kind (index position in kind_set) for this atom (atomic_kind)
428 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
429 ! get the primary (orbital) basis set associated to this qs_kind
430 CALL get_qs_kind(kind_set(ikind), basis_set=basis_set, basis_type="ORB")
431 ! get the info from the basis set
432 CALL get_gto_basis_set(basis_set, &
433 nset=nset, &
434 nshell=nshell, &
435 npgf=npgf, &
436 zet=zetas, &
437 gcc=gcc, &
438 l=l_shell_set)
439
440 DO iset = 1, nset
441 DO ishell_loc = 1, nshell(iset)
442 ishell = ishell + 1
443
444 ! nucleus_index array
445 nucleus_index(ishell) = iatom
446
447 ! shell_ang_mom array
448 l = l_shell_set(ishell_loc, iset)
449 shell_ang_mom(ishell) = l
450
451 ! shell_index array
452 shell_index(ipgf + 1:ipgf + npgf(iset)) = ishell
453
454 ! exponents array
455 exponents(ipgf + 1:ipgf + npgf(iset)) = zetas(1:npgf(iset), iset)
456
457 ! compute on the fly the normalization factor as in normalise_gcc_orb
458 ! and recover the original contraction coefficients to store them separately
459 expzet = 0.25_dp*real(2*l + 3, dp)
460 prefac = 2.0_dp**l*(2.0_dp/pi)**0.75_dp
461 DO i = 1, npgf(iset)
462 gcca = gcc(i, ishell_loc, iset)
463 zeta = zetas(i, iset)
464 prim_cart_fac = prefac*zeta**expzet
465
466 ! contraction coefficients array
467 coefficients(ipgf + i) = gcca/prim_cart_fac
468
469 IF (save_cartesian) THEN
470 ! primitives normalization factors array
471 prim_factor(ipgf + i) = prim_cart_fac
472 ELSE
473 ! for spherical harmonics we have a different factor
474 prim_factor(ipgf + i) = sgf_norm(l, exponents(ipgf + i))
475 ! we need these later in the AO group
476 sgf_coefficients(ipgf + i) = coefficients(ipgf + i)*prim_factor(ipgf + i)
477 END IF
478
479 END DO
480
481 ipgf = ipgf + npgf(iset)
482 END DO
483 END DO
484 END DO
485 ! just a failsafe check
486 cpassert(ishell == shell_num)
487 cpassert(ipgf == prim_num)
488
489 IF (ionode) THEN
490 rc = trexio_write_basis_nucleus_index(f, nucleus_index)
491 CALL trexio_error(rc)
492
493 rc = trexio_write_basis_shell_ang_mom(f, shell_ang_mom)
494 CALL trexio_error(rc)
495
496 ! Normalization factors are shoved in the AO group
497 ALLOCATE (shell_factor(shell_num)) ! 1-to-1 map bw shells and normalization factors
498 shell_factor(:) = 1.0_dp
499 rc = trexio_write_basis_shell_factor(f, shell_factor)
500 CALL trexio_error(rc)
501 DEALLOCATE (shell_factor)
502
503 ! This is always 0 for Gaussian basis sets
504 ALLOCATE (r_power(shell_num)) ! 1-to-1 map bw shells radial function powers
505 r_power(:) = 0
506 rc = trexio_write_basis_r_power(f, r_power)
507 CALL trexio_error(rc)
508 DEALLOCATE (r_power)
509
510 rc = trexio_write_basis_shell_index(f, shell_index)
511 CALL trexio_error(rc)
512
513 rc = trexio_write_basis_exponent(f, exponents)
514 CALL trexio_error(rc)
515
516 rc = trexio_write_basis_coefficient(f, coefficients)
517 CALL trexio_error(rc)
518
519 ! Normalization factors are shoved in the AO group
520 rc = trexio_write_basis_prim_factor(f, prim_factor)
521 CALL trexio_error(rc)
522 END IF
523
524 DEALLOCATE (nucleus_index)
525 DEALLOCATE (shell_index)
526 DEALLOCATE (exponents)
527 DEALLOCATE (coefficients)
528 DEALLOCATE (prim_factor)
529 ! shell_ang_mom is needed in the MO group, so will be deallocated there
530
531 !========================================================================================!
532 ! ECP group
533 !========================================================================================!
534 IF (ionode) THEN
535 CALL get_qs_kind_set(kind_set, sgp_potential_present=sgp_potential_present)
536
537 ! figure out whether we actually have ECP potentials
538 ecp_num = 0
539 IF (sgp_potential_present) THEN
540 DO iatom = 1, natoms
541 ! get the qs_kind (index position in kind_set) for this atom (atomic_kind)
542 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
543 ! get the the sgp_potential associated to this qs_kind
544 CALL get_qs_kind(kind_set(ikind), sgp_potential=sgp_potential)
545
546 ! get the info on the potential
547 IF (ASSOCIATED(sgp_potential)) THEN
548 CALL get_potential(potential=sgp_potential, ecp_local=ecp_local, ecp_semi_local=ecp_semi_local)
549 IF (ecp_local) THEN
550 ! get number of local terms
551 CALL get_potential(potential=sgp_potential, nloc=nloc)
552 ecp_num = ecp_num + nloc
553 END IF
554 IF (ecp_semi_local) THEN
555 ! get number of semilocal terms
556 CALL get_potential(potential=sgp_potential, npot=npot)
557 ecp_num = ecp_num + sum(npot)
558 END IF
559 END IF
560 END DO
561 END IF
562
563 ! if we have ECP potentials, populate the ECP group
564 IF (ecp_num > 0) THEN
565 ALLOCATE (z_core(natoms))
566 ALLOCATE (max_ang_mom_plus_1(natoms))
567 max_ang_mom_plus_1(:) = 0
568
569 ALLOCATE (ang_mom(ecp_num))
570 ALLOCATE (nucleus_index(ecp_num))
571 ALLOCATE (exponents(ecp_num))
572 ALLOCATE (ecp_coefficients(ecp_num))
573 ALLOCATE (powers(ecp_num))
574
575 iecp = 0
576 DO iatom = 1, natoms
577 ! get the qs_kind (index position in kind_set) for this atom (atomic_kind)
578 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind, z=z)
579 ! get the the sgp_potential associated to this qs_kind
580 CALL get_qs_kind(kind_set(ikind), sgp_potential=sgp_potential, zeff=zeff)
581
582 ! number of core electrons removed by the ECP
583 z_core(iatom) = z - int(zeff)
584
585 ! get the info on the potential
586 IF (ASSOCIATED(sgp_potential)) THEN
587 CALL get_potential(potential=sgp_potential, ecp_local=ecp_local, ecp_semi_local=ecp_semi_local)
588
589 ! deal with the local part
590 IF (ecp_local) THEN
591 CALL get_potential(potential=sgp_potential, nloc=nloc, sl_lmax=sl_lmax)
592 ang_mom(iecp + 1:iecp + nloc) = sl_lmax + 1
593 nucleus_index(iecp + 1:iecp + nloc) = iatom
594 exponents(iecp + 1:iecp + nloc) = sgp_potential%bloc(1:nloc)
595 ecp_coefficients(iecp + 1:iecp + nloc) = sgp_potential%aloc(1:nloc)
596 powers(iecp + 1:iecp + nloc) = sgp_potential%nrloc(1:nloc) - 2
597 iecp = iecp + nloc
598 END IF
599
600 ! deal with the semilocal part
601 IF (ecp_semi_local) THEN
602 CALL get_potential(potential=sgp_potential, npot=npot, sl_lmax=sl_lmax)
603 max_ang_mom_plus_1(iatom) = sl_lmax + 1
604
605 DO sl_l = 0, sl_lmax
606 nsemiloc = npot(sl_l)
607 ang_mom(iecp + 1:iecp + nsemiloc) = sl_l
608 nucleus_index(iecp + 1:iecp + nsemiloc) = iatom
609 exponents(iecp + 1:iecp + nsemiloc) = sgp_potential%bpot(1:nsemiloc, sl_l)
610 ecp_coefficients(iecp + 1:iecp + nsemiloc) = sgp_potential%apot(1:nsemiloc, sl_l)
611 powers(iecp + 1:iecp + nsemiloc) = sgp_potential%nrpot(1:nsemiloc, sl_l) - 2
612 iecp = iecp + nsemiloc
613 END DO
614 END IF
615 END IF
616 END DO
617
618 ! fail-safe check
619 cpassert(iecp == ecp_num)
620
621 rc = trexio_write_ecp_num(f, ecp_num)
622 CALL trexio_error(rc)
623
624 rc = trexio_write_ecp_z_core(f, z_core)
625 CALL trexio_error(rc)
626 DEALLOCATE (z_core)
627
628 rc = trexio_write_ecp_max_ang_mom_plus_1(f, max_ang_mom_plus_1)
629 CALL trexio_error(rc)
630 DEALLOCATE (max_ang_mom_plus_1)
631
632 rc = trexio_write_ecp_ang_mom(f, ang_mom)
633 CALL trexio_error(rc)
634 DEALLOCATE (ang_mom)
635
636 rc = trexio_write_ecp_nucleus_index(f, nucleus_index)
637 CALL trexio_error(rc)
638 DEALLOCATE (nucleus_index)
639
640 rc = trexio_write_ecp_exponent(f, exponents)
641 CALL trexio_error(rc)
642 DEALLOCATE (exponents)
643
644 rc = trexio_write_ecp_coefficient(f, ecp_coefficients)
645 CALL trexio_error(rc)
646 DEALLOCATE (ecp_coefficients)
647
648 rc = trexio_write_ecp_power(f, powers)
649 CALL trexio_error(rc)
650 DEALLOCATE (powers)
651 END IF
652
653 END IF ! ionode
654
655 !========================================================================================!
656 ! Grid group
657 !========================================================================================!
658 ! TODO
659
660 !========================================================================================!
661 ! AO group
662 !========================================================================================!
663 CALL get_qs_env(qs_env, qs_kind_set=kind_set)
664 CALL get_qs_kind_set(kind_set, ncgf=ncgf, nsgf=nsgf)
665
666 IF (save_cartesian) THEN
667 ao_num = ncgf
668 ELSE
669 ao_num = nsgf
670 END IF
671
672 IF (ionode) THEN
673 IF (save_cartesian) THEN
674 rc = trexio_write_ao_cartesian(f, 1)
675 ELSE
676 rc = trexio_write_ao_cartesian(f, 0)
677 END IF
678 CALL trexio_error(rc)
679
680 rc = trexio_write_ao_num(f, ao_num)
681 CALL trexio_error(rc)
682 END IF
683
684 ! one-to-one mapping between AOs and ...
685 ALLOCATE (ao_shell(ao_num)) ! ..shells
686 ALLOCATE (ao_normalization(ao_num)) ! ..normalization factors
687 ALLOCATE (ao_to_atom(ao_num)) ! ..parent atom (needed for the k-point gauge fix)
688
689 IF (.NOT. save_cartesian) THEN
690 ! AO order map from CP2K to TREXIO convention
691 ! from m = -l, -l+1, ..., 0, ..., l-1, l of CP2K
692 ! to m = 0, +1, -1, +2, -2, ..., +l, -l of TREXIO
693 ALLOCATE (cp2k_to_trexio_ang_mom(ao_num))
694 i = 0
695 DO ishell = 1, shell_num
696 l = shell_ang_mom(ishell)
697 DO k = 1, 2*l + 1
698 m = (-1)**k*floor(real(k, kind=dp)/2.0_dp)
699 cp2k_to_trexio_ang_mom(i + k) = i + l + 1 + m
700 END DO
701 i = i + 2*l + 1
702 END DO
703 cpassert(i == ao_num)
704 END IF
705
706 ! we need to be consistent with the basis group on the shell indices
707 ishell = 0 ! global shell index
708 iao = 0 ! global AO index
709 ipgf = 0 ! global primitives index
710 DO iatom = 1, natoms
711 ! get the qs_kind (index position in kind_set) for this atom (atomic_kind)
712 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
713 ! get the primary (orbital) basis set associated to this qs_kind
714 CALL get_qs_kind(kind_set(ikind), basis_set=basis_set, basis_type="ORB")
715 ! get the info from the basis set
716 CALL get_gto_basis_set(basis_set, &
717 nset=nset, &
718 nshell=nshell, &
719 norm_cgf=norm_cgf, &
720 ncgf=ncgf_atom, &
721 npgf=npgf, &
722 zet=zetas, &
723 l=l_shell_set)
724
725 icgf_atom = 0
726 DO iset = 1, nset
727 DO ishell_loc = 1, nshell(iset)
728 ! global shell index
729 ishell = ishell + 1
730 ! angular momentum l of this shell
731 l = l_shell_set(ishell_loc, iset)
732
733 ! number of AOs in this shell
734 IF (save_cartesian) THEN
735 nao_shell = nco(l)
736 ELSE
737 nao_shell = nso(l)
738 END IF
739
740 ! one-to-one mapping between AOs and shells
741 ao_shell(iao + 1:iao + nao_shell) = ishell
742
743 ! one-to-one mapping between AOs and parent atoms
744 ao_to_atom(iao + 1:iao + nao_shell) = iatom
745
746 ! one-to-one mapping between AOs and normalization factors
747 IF (save_cartesian) THEN
748 ao_normalization(iao + 1:iao + nao_shell) = norm_cgf(icgf_atom + 1:icgf_atom + nao_shell)
749 ELSE
750 ! for each shell, compute the overlap between spherical primitives
751 ALLOCATE (sloc(npgf(iset), npgf(iset)))
752 ALLOCATE (sgcc(npgf(iset)))
753 CALL sg_overlap(sloc, l, zetas(1:npgf(iset), iset), zetas(1:npgf(iset), iset))
754
755 ! and compute the normalizaztion factor for contracted spherical GTOs
756 sgcc(:) = matmul(sloc, sgf_coefficients(ipgf + 1:ipgf + npgf(iset)))
757 nsgto = 1.0_dp/sqrt(dot_product(sgf_coefficients(ipgf + 1:ipgf + npgf(iset)), sgcc))
758
759 DEALLOCATE (sloc)
760 DEALLOCATE (sgcc)
761
762 ! TREXIO employs solid harmonics and not spherical harmonics like cp2k
763 ! so we need the opposite of Racah normalization, multiplied by the Nsgto
764 ! just computed above
765 ao_normalization(iao + 1:iao + nao_shell) = nsgto*sqrt((2*l + 1)/(4*pi))
766 END IF
767
768 ipgf = ipgf + npgf(iset)
769 iao = iao + nao_shell
770 icgf_atom = icgf_atom + nco(l)
771 END DO
772 END DO
773 ! just a failsafe check
774 cpassert(icgf_atom == ncgf_atom)
775 END DO
776
777 IF (ionode) THEN
778 rc = trexio_write_ao_shell(f, ao_shell)
779 CALL trexio_error(rc)
780
781 rc = trexio_write_ao_normalization(f, ao_normalization)
782 CALL trexio_error(rc)
783 END IF
784
785 DEALLOCATE (ao_shell)
786 DEALLOCATE (ao_normalization)
787 IF (ALLOCATED(sgf_coefficients)) DEALLOCATE (sgf_coefficients)
788
789 !========================================================================================!
790 ! MO group
791 !========================================================================================!
792 CALL get_qs_env(qs_env, do_kpoints=do_kpoints, kpoints=kpoints, dft_control=dft_control, &
793 particle_set=particle_set, qs_kind_set=kind_set, blacs_env=blacs_env, &
794 cell=cell)
795 nspins = dft_control%nspins
796 CALL get_qs_kind_set(kind_set, nsgf=nsgf, ncgf=ncgf)
797 nmo_spin = 0
798
799 ! figure out that total number of MOs
800 mo_num = 0
801 IF (do_kpoints) THEN
802 CALL get_kpoint_info(trexio_kpoints, kp_env=kp_env, nkp=nkp, use_real_wfn=use_real_wfn)
803 CALL get_kpoint_env(kp_env(1)%kpoint_env, mos=mos_kp)
804 DO ispin = 1, nspins
805 CALL get_mo_set(mos_kp(1, ispin), nmo=nmo)
806 nmo_spin(ispin) = nmo
807 END DO
808 mo_num = nkp*sum(nmo_spin)
809
810 ! we create a distributed fm matrix to gather the MOs from everywhere (in sph basis)
811 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
812 nrow_global=nsgf, ncol_global=mo_num)
813 CALL cp_fm_create(fm_mo_coeff, fm_struct)
814 CALL cp_fm_set_all(fm_mo_coeff, 0.0_dp)
815 IF (.NOT. use_real_wfn) THEN
816 CALL cp_fm_create(fm_mo_coeff_im, fm_struct)
817 CALL cp_fm_set_all(fm_mo_coeff_im, 0.0_dp)
818 END IF
819 CALL cp_fm_struct_release(fm_struct)
820 ELSE
821 CALL get_qs_env(qs_env, mos=mos)
822 DO ispin = 1, nspins
823 CALL get_mo_set(mos(ispin), nmo=nmo)
824 nmo_spin(ispin) = nmo
825 END DO
826 mo_num = sum(nmo_spin)
827 END IF
828
829 ! allocate all the arrays
830 ALLOCATE (mo_coefficient(ao_num, mo_num))
831 mo_coefficient(:, :) = 0.0_dp
832 ALLOCATE (mo_energy(mo_num))
833 mo_energy(:) = 0.0_dp
834 ALLOCATE (mo_occupation(mo_num))
835 mo_occupation(:) = 0.0_dp
836 ALLOCATE (mo_spin(mo_num))
837 mo_spin(:) = 0
838 ! extra arrays for kpoints
839 IF (do_kpoints) THEN
840 ALLOCATE (mo_coefficient_im(ao_num, mo_num))
841 mo_coefficient_im(:, :) = 0.0_dp
842 ALLOCATE (mo_kpoint(mo_num))
843 mo_kpoint(:) = 0
844 END IF
845
846 ! in case of kpoints, we do this in 2 steps:
847 ! 1. we gather the MOs of each kpt and pipe them into a single large distributed fm matrix;
848 ! 2. we possibly transform the MOs of each kpt to Cartesian AOs and write them in the single large local array;
849 IF (do_kpoints) THEN
850 CALL get_kpoint_info(trexio_kpoints, kp_env=kp_env, nkp=nkp, kp_range=kp_range)
851
852 DO ispin = 1, nspins
853 DO ikp = 1, nkp
854 nmo = nmo_spin(ispin)
855 ! global index to store the MOs
856 imo = (ikp - 1)*nmo + (ispin - 1)*nmo_spin(1)*nkp
857
858 ! do I have this kpoint on this rank?
859 IF (ikp >= kp_range(1) .AND. ikp <= kp_range(2)) THEN
860 ikp_loc = ikp - kp_range(1) + 1
861 ! get the mo set for this kpoint
862 CALL get_kpoint_env(kp_env(ikp_loc)%kpoint_env, mos=mos_kp)
863
864 ! if MOs are stored with dbcsr, copy them to fm
865 IF (mos_kp(1, ispin)%use_mo_coeff_b) THEN
866 CALL copy_dbcsr_to_fm(mos_kp(1, ispin)%mo_coeff_b, mos_kp(1, ispin)%mo_coeff)
867 END IF
868 ! copy real part of MO coefficients to large distributed fm matrix
869 CALL cp_fm_to_fm_submat_general(mos_kp(1, ispin)%mo_coeff, fm_mo_coeff, &
870 nsgf, nmo, 1, 1, 1, imo + 1, blacs_env)
871
872 ! copy MO energies to local arrays
873 mo_energy(imo + 1:imo + nmo) = mos_kp(1, ispin)%eigenvalues(1:nmo)
874
875 ! copy MO occupations to local arrays
876 mo_occupation(imo + 1:imo + nmo) = mos_kp(1, ispin)%occupation_numbers(1:nmo)
877
878 ! same for the imaginary part of MO coefficients
879 IF (.NOT. use_real_wfn) THEN
880 IF (mos_kp(2, ispin)%use_mo_coeff_b) THEN
881 CALL copy_dbcsr_to_fm(mos_kp(2, ispin)%mo_coeff_b, mos_kp(2, ispin)%mo_coeff)
882 END IF
883 CALL cp_fm_to_fm_submat_general(mos_kp(2, ispin)%mo_coeff, fm_mo_coeff_im, &
884 nsgf, nmo, 1, 1, 1, imo + 1, blacs_env)
885 END IF
886 ELSE
887 ! call with a dummy fm for receiving the data
888 CALL cp_fm_to_fm_submat_general(fm_dummy, fm_mo_coeff, &
889 nsgf, nmo, 1, 1, 1, imo + 1, blacs_env)
890 IF (.NOT. use_real_wfn) THEN
891 CALL cp_fm_to_fm_submat_general(fm_dummy, fm_mo_coeff_im, &
892 nsgf, nmo, 1, 1, 1, imo + 1, blacs_env)
893 END IF
894 END IF
895 END DO
896 END DO
897 END IF
898
899 ! reduce MO energies and occupations to the master node
900 IF (do_kpoints) THEN
901 CALL get_kpoint_info(trexio_kpoints, para_env_inter_kp=para_env_inter_kp)
902 CALL para_env_inter_kp%sum(mo_energy)
903 CALL para_env_inter_kp%sum(mo_occupation)
904 END IF
905
906 ! Bloch-gauge correction (k-points, complex wfn only):
907 ! Build per-atom agauge matching kpoint_methods.F :: kpoint_initialize. The MO
908 ! coefficients gathered above are referenced to atoms wrapped into [-1/2, 1/2),
909 ! while nucleus_coord was written using the raw particle_set(i)%r. We compensate
910 ! by multiplying each AO column block by exp(-i 2*pi * k * agauge_i) per k-point.
911 IF (do_kpoints .AND. .NOT. use_real_wfn) THEN
912 CALL get_kpoint_info(trexio_kpoints, xkp=xkp)
913 ALLOCATE (agauge(3, natoms))
914 DO iatom = 1, natoms
915 CALL real_to_scaled(scoord, particle_set(iatom)%r(1:3), cell)
916 IF (kpoints%symmetry) THEN
917 r_pbc = pbc_stable(particle_set(iatom)%r(1:3), cell)
918 ELSE
919 r_pbc = pbc(particle_set(iatom)%r(1:3), cell)
920 END IF
921 CALL real_to_scaled(scoord_pbc, r_pbc, cell)
922 agauge(:, iatom) = nint(scoord_pbc - scoord)
923 END DO
924 END IF
925
926 ! second step: here we actually put everything in the local arrays for writing to trexio
927 DO ispin = 1, nspins
928 ! get number of MOs for this spin
929 nmo = nmo_spin(ispin)
930 ! allocate local temp array to transform the MOs of each kpoint/spin
931 ALLOCATE (mos_sgf(nsgf, nmo))
932 mos_sgf(:, :) = 0.0_dp
933
934 IF (do_kpoints) THEN
935 DO ikp = 1, nkp
936 ! global index to store the MOs
937 imo = (ikp - 1)*nmo + (ispin - 1)*nmo_spin(1)*nkp
938
939 ! store kpoint index
940 mo_kpoint(imo + 1:imo + nmo) = ikp
941 ! store the MO spins
942 mo_spin(imo + 1:imo + nmo) = ispin - 1
943
944 ! transform and store the MO coefficients
945 CALL cp_fm_get_submatrix(fm_mo_coeff, mos_sgf, 1, imo + 1, nsgf, nmo)
946 IF (save_cartesian) THEN
947 CALL spherical_to_cartesian_mo(mos_sgf, particle_set, kind_set, mo_coefficient(:, imo + 1:imo + nmo))
948 ELSE
949 ! we have to reorder the MOs since CP2K and TREXIO have different conventions
950 DO i = 1, nsgf
951 mo_coefficient(i, imo + 1:imo + nmo) = mos_sgf(cp2k_to_trexio_ang_mom(i), :)
952 END DO
953 END IF
954
955 ! we have to do it for the imaginary part as well
956 IF (.NOT. use_real_wfn) THEN
957 CALL cp_fm_get_submatrix(fm_mo_coeff_im, mos_sgf, 1, imo + 1, nsgf, nmo)
958 IF (save_cartesian) THEN
959 CALL spherical_to_cartesian_mo(mos_sgf, particle_set, kind_set, mo_coefficient_im(:, imo + 1:imo + nmo))
960 ELSE
961 ! we have to reorder the MOs since CP2K and TREXIO have different conventions
962 DO i = 1, nsgf
963 mo_coefficient_im(i, imo + 1:imo + nmo) = mos_sgf(cp2k_to_trexio_ang_mom(i), :)
964 END DO
965 END IF
966
967 ! Apply per-atom Bloch-gauge phase factor exp(-i 2*pi * k_ikp * agauge_iatom)
968 ! to remove the spurious phase the consumer would otherwise pick up from
969 ! the (raw nucleus_coord, agauge-gauge MO) mismatch.
970 DO iao = 1, ao_num
971 iatom = ao_to_atom(iao)
972 kdotg = 2.0_dp*pi*dot_product(xkp(:, ikp), real(agauge(:, iatom), kind=dp))
973 cval = cos(kdotg)
974 sval = sin(kdotg)
975 DO j = imo + 1, imo + nmo
976 re_old = mo_coefficient(iao, j)
977 im_old = mo_coefficient_im(iao, j)
978 mo_coefficient(iao, j) = cval*re_old + sval*im_old
979 mo_coefficient_im(iao, j) = -sval*re_old + cval*im_old
980 END DO
981 END DO
982 END IF
983 END DO
984 ELSE ! no k-points
985 ! global index to store the MOs
986 imo = (ispin - 1)*nmo_spin(1)
987 ! store the MO energies
988 mo_energy(imo + 1:imo + nmo) = mos(ispin)%eigenvalues
989 ! store the MO occupations
990 mo_occupation(imo + 1:imo + nmo) = mos(ispin)%occupation_numbers
991 ! store the MO spins
992 mo_spin(imo + 1:imo + nmo) = ispin - 1
993
994 ! check if we are using the dbcsr mo_coeff and copy them to fm if needed
995 IF (mos(ispin)%use_mo_coeff_b) CALL copy_dbcsr_to_fm(mos(ispin)%mo_coeff_b, mos(ispin)%mo_coeff)
996
997 ! allocate a normal fortran array to store the spherical MO coefficients
998 CALL cp_fm_get_submatrix(mos(ispin)%mo_coeff, mos_sgf)
999
1000 IF (save_cartesian) THEN
1001 CALL spherical_to_cartesian_mo(mos_sgf, particle_set, kind_set, mo_coefficient(:, imo + 1:imo + nmo))
1002 ELSE
1003 ! we have to reorder the MOs since CP2K and TREXIO have different conventions
1004 DO i = 1, nsgf
1005 mo_coefficient(i, imo + 1:imo + nmo) = mos_sgf(cp2k_to_trexio_ang_mom(i), :)
1006 END DO
1007 END IF
1008 END IF
1009
1010 DEALLOCATE (mos_sgf)
1011 END DO
1012
1013 IF (ionode) THEN
1014 rc = trexio_write_mo_type(f, 'Canonical', len_trim('Canonical') + 1)
1015 CALL trexio_error(rc)
1016
1017 rc = trexio_write_mo_num(f, mo_num)
1018 CALL trexio_error(rc)
1019
1020 rc = trexio_write_mo_coefficient(f, mo_coefficient)
1021 CALL trexio_error(rc)
1022
1023 rc = trexio_write_mo_energy(f, mo_energy)
1024 CALL trexio_error(rc)
1025
1026 rc = trexio_write_mo_occupation(f, mo_occupation)
1027 CALL trexio_error(rc)
1028
1029 rc = trexio_write_mo_spin(f, mo_spin)
1030 CALL trexio_error(rc)
1031
1032 IF (do_kpoints) THEN
1033 rc = trexio_write_mo_coefficient_im(f, mo_coefficient_im)
1034 CALL trexio_error(rc)
1035
1036 rc = trexio_write_mo_k_point(f, mo_kpoint)
1037 CALL trexio_error(rc)
1038 END IF
1039 END IF
1040
1041 DEALLOCATE (mo_coefficient)
1042 DEALLOCATE (mo_energy)
1043 DEALLOCATE (mo_occupation)
1044 DEALLOCATE (mo_spin)
1045 IF (do_kpoints) THEN
1046 DEALLOCATE (mo_coefficient_im)
1047 DEALLOCATE (mo_kpoint)
1048 CALL cp_fm_release(fm_mo_coeff)
1049 CALL cp_fm_release(fm_mo_coeff_im)
1050 END IF
1051 IF (ALLOCATED(ao_to_atom)) DEALLOCATE (ao_to_atom)
1052 IF (ALLOCATED(agauge)) DEALLOCATE (agauge)
1053 IF (trexio_kpoints_created) CALL kpoint_release(trexio_kpoints)
1054
1055 !========================================================================================!
1056 ! RDM group
1057 !========================================================================================!
1058 !TODO
1059
1060 !========================================================================================!
1061 ! Energy derivative group
1062 !========================================================================================!
1063 IF (PRESENT(energy_derivative)) THEN
1064 filename_de = trim(logger%iter_info%project_name)//'-TREXIO.dEdP.dat'
1065
1066 ALLOCATE (dedp(nsgf, nsgf))
1067 dedp(:, :) = 0.0_dp
1068
1069 DO ispin = 1, nspins
1070 CALL dbcsr_iterator_start(iter, energy_derivative(ispin)%matrix)
1071 DO WHILE (dbcsr_iterator_blocks_left(iter))
1072 ! the offsets tell me the global index of the matrix, not the index of the block
1073 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
1074 row_size=row_size, col_size=col_size, &
1075 row_offset=row_offset, col_offset=col_offset)
1076
1077 ! Copy data from block to array
1078 DO i = 1, row_size
1079 DO j = 1, col_size
1080 dedp(row_offset + i - 1, col_offset + j - 1) = data_block(i, j)
1081 END DO
1082 END DO
1083 END DO
1084 CALL dbcsr_iterator_stop(iter)
1085
1086 ! symmetrize the matrix if needed
1087 SELECT CASE (dbcsr_get_matrix_type(energy_derivative(ispin)%matrix))
1088 CASE (dbcsr_type_symmetric)
1089 CALL symmetrize_matrix(dedp, "upper_to_lower")
1090 CASE (dbcsr_type_antisymmetric)
1091 CALL symmetrize_matrix(dedp, "anti_upper_to_lower")
1092 CASE (dbcsr_type_no_symmetry)
1093 CASE DEFAULT
1094 cpabort("Unknown matrix type for energy derivative")
1095 END SELECT
1096 END DO
1097
1098 ! reduce the dEdP matrix to the master node
1099 CALL para_env%sum(dedp)
1100
1101 ! print the dEdP matrix to a file
1102 IF (ionode) THEN
1103 WRITE (output_unit, "((T2,A,A))") 'TREXIO| Writing derivative file ', trim(filename_de)
1104
1105 unit_de = 10
1106 CALL open_file(file_name=filename_de, &
1107 file_action="WRITE", &
1108 file_status="UNKNOWN", &
1109 unit_number=unit_de)
1110 WRITE (unit_de, '(I0, 1X, I0)') nsgf, nsgf
1111 DO i = 1, nsgf
1112 WRITE (unit_de, '(*(1X, F15.8))') (dedp(cp2k_to_trexio_ang_mom(i), &
1113 cp2k_to_trexio_ang_mom(j)), j=1, nsgf)
1114 END DO
1115 CALL close_file(unit_number=unit_de)
1116 END IF
1117
1118 DEALLOCATE (dedp)
1119 END IF
1120
1121 ! Deallocate arrays used throughout the subroutine
1122 IF (ALLOCATED(shell_ang_mom)) DEALLOCATE (shell_ang_mom)
1123 IF (ALLOCATED(cp2k_to_trexio_ang_mom)) DEALLOCATE (cp2k_to_trexio_ang_mom)
1124
1125 !========================================================================================!
1126 ! Close the TREXIO file
1127 !========================================================================================!
1128 IF (ionode) THEN
1129 rc = trexio_close(f)
1130 CALL trexio_error(rc)
1131 END IF
1132
1133 CALL timestop(handle)
1134#else
1135 mark_used(qs_env)
1136 mark_used(trexio_section)
1137 mark_used(energy_derivative)
1138 cpwarn('TREXIO support has not been enabled in this build.')
1139#endif
1140
1141 END SUBROUTINE write_trexio
1142
1143! **************************************************************************************************
1144!> \brief Prepare the k-point object used for TREXIO export.
1145!> \param qs_env the QS environment
1146!> \param trexio_section the TREXIO print section
1147!> \param do_kpoints true when the SCF used k-points
1148!> \param kpoints_scf the converged SCF k-point object
1149!> \param kpoints_out the k-point object to write
1150!> \param created true if kpoints_out must be released by the caller
1151! **************************************************************************************************
1152 SUBROUTINE prepare_trexio_kpoint_grid(qs_env, trexio_section, do_kpoints, kpoints_scf, &
1153 kpoints_out, created)
1154 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1155 TYPE(section_vals_type), INTENT(IN), POINTER :: trexio_section
1156 LOGICAL, INTENT(IN) :: do_kpoints
1157 TYPE(kpoint_type), POINTER :: kpoints_scf, kpoints_out
1158 LOGICAL, INTENT(OUT) :: created
1159
1160#ifdef __TREXIO
1161 CHARACTER(LEN=*), PARAMETER :: routinen = 'prepare_trexio_kpoint_grid'
1162
1163 CHARACTER(LEN=default_string_length) :: kp_scheme, reuse_reason
1164 INTEGER :: aligned_blocks, aligned_max_size, handle, &
1165 nfull, output_unit
1166 INTEGER, DIMENSION(3) :: nkp_grid
1167 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1168 LOGICAL :: diis_step, full_grid, full_kpoint_grid, &
1169 gamma_centered, reuse_scf_mos, &
1170 reused_scf_mos, symmetry
1171 REAL(kind=dp) :: aligned_min_svalue, eps_geo, wsum
1172 REAL(kind=dp), DIMENSION(3) :: kp_shift
1173 REAL(kind=dp), DIMENSION(:), POINTER :: wkp_source
1174 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp_source
1175 TYPE(cell_type), POINTER :: cell
1176 TYPE(cp_blacs_env_type), POINTER :: blacs_env
1177 TYPE(cp_logger_type), POINTER :: logger
1178 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
1179 TYPE(dft_control_type), POINTER :: dft_control
1180 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1181 TYPE(mp_para_env_type), POINTER :: para_env
1182 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1183 POINTER :: sab_nl
1184 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1185 TYPE(qs_scf_env_type), POINTER :: scf_env
1186 TYPE(scf_control_type), POINTER :: scf_control
1187
1188 CALL timeset(routinen, handle)
1189
1190 created = .false.
1191 kpoints_out => kpoints_scf
1192 NULLIFY (blacs_env, cell, cell_to_index, dft_control, logger, matrix_ks, matrix_s, mos, &
1193 para_env, particle_set, sab_nl, scf_control, scf_env, wkp_source, xkp_source)
1194
1195 CALL section_vals_val_get(trexio_section, "FULL_KPOINT_GRID", l_val=full_kpoint_grid)
1196 IF (.NOT. do_kpoints .OR. .NOT. full_kpoint_grid) THEN
1197 CALL timestop(handle)
1198 RETURN
1199 END IF
1200 cpassert(ASSOCIATED(kpoints_scf))
1201
1202 CALL get_kpoint_info(kpoints_scf, kp_scheme=kp_scheme, symmetry=symmetry, &
1203 full_grid=full_grid, nkp_grid=nkp_grid, kp_shift=kp_shift, &
1204 gamma_centered=gamma_centered, eps_geo=eps_geo)
1205 IF (.NOT. symmetry .OR. full_grid) THEN
1206 CALL timestop(handle)
1207 RETURN
1208 END IF
1209
1210 SELECT CASE (trim(kp_scheme))
1211 CASE ("MONKHORST-PACK", "MACDONALD", "GENERAL")
1212 ! supported below
1213 CASE DEFAULT
1214 cpabort("TREXIO%FULL_KPOINT_GRID supports only MONKHORST-PACK, MACDONALD, and GENERAL k-points.")
1215 END SELECT
1216
1217 logger => cp_get_default_logger()
1218 output_unit = cp_logger_get_default_io_unit(logger)
1219 CALL section_vals_val_get(trexio_section, "REUSE_SCF_MOS", l_val=reuse_scf_mos)
1220 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell, &
1221 particle_set=particle_set, mos=mos, dft_control=dft_control, &
1222 sab_orb=sab_nl, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s, &
1223 scf_env=scf_env, scf_control=scf_control)
1224 cpassert(ASSOCIATED(para_env))
1225 cpassert(ASSOCIATED(blacs_env))
1226 cpassert(ASSOCIATED(cell))
1227 cpassert(ASSOCIATED(particle_set))
1228 cpassert(ASSOCIATED(mos))
1229 cpassert(ASSOCIATED(dft_control))
1230 cpassert(ASSOCIATED(sab_nl))
1231 cpassert(ASSOCIATED(matrix_ks))
1232 cpassert(ASSOCIATED(matrix_s))
1233 cpassert(ASSOCIATED(scf_env))
1234 cpassert(ASSOCIATED(scf_control))
1235
1236 NULLIFY (kpoints_out)
1237 CALL kpoint_create(kpoints_out)
1238 kpoints_out%kp_scheme = kp_scheme
1239 kpoints_out%symmetry = .false.
1240 kpoints_out%full_grid = .true.
1241 kpoints_out%verbose = .false.
1242 kpoints_out%use_real_wfn = .false.
1243 kpoints_out%eps_geo = eps_geo
1244 kpoints_out%parallel_group_size = para_env%num_pe
1245
1246 SELECT CASE (trim(kp_scheme))
1247 CASE ("MONKHORST-PACK", "MACDONALD")
1248 kpoints_out%nkp_grid(1:3) = nkp_grid(1:3)
1249 kpoints_out%kp_shift(1:3) = kp_shift(1:3)
1250 kpoints_out%gamma_centered = gamma_centered
1251 CALL kpoint_initialize(kpoints_out, particle_set, cell)
1252 CASE ("GENERAL")
1253 IF (.NOT. ASSOCIATED(kpoints_scf%xkp_input) .OR. &
1254 .NOT. ASSOCIATED(kpoints_scf%wkp_input)) THEN
1255 cpabort("TREXIO%FULL_KPOINT_GRID cannot recover the unreduced GENERAL k-point set.")
1256 END IF
1257 xkp_source => kpoints_scf%xkp_input
1258 wkp_source => kpoints_scf%wkp_input
1259 nfull = SIZE(wkp_source)
1260 wsum = sum(wkp_source)
1261 IF (wsum <= 0.0_dp) cpabort("TREXIO%FULL_KPOINT_GRID found invalid GENERAL k-point weights.")
1262 kpoints_out%nkp = nfull
1263 ALLOCATE (kpoints_out%xkp(3, nfull), kpoints_out%wkp(nfull))
1264 kpoints_out%xkp(1:3, 1:nfull) = xkp_source(1:3, 1:nfull)
1265 kpoints_out%wkp(1:nfull) = wkp_source(1:nfull)/wsum
1266 END SELECT
1267
1268 CALL kpoint_env_initialize(kpoints_out, para_env, blacs_env)
1269 CALL kpoint_initialize_mos(kpoints_out, mos)
1270 CALL kpoint_initialize_mo_set(kpoints_out)
1271 CALL kpoint_init_cell_index(kpoints_out, sab_nl, para_env, dft_control%nimages)
1272
1273 reused_scf_mos = .false.
1274 reuse_reason = ""
1275 aligned_blocks = 0
1276 aligned_max_size = 0
1277 aligned_min_svalue = 0.0_dp
1278 diis_step = .false.
1279 IF (reuse_scf_mos) THEN
1280 CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints_scf, scf_env, scf_control, .false., &
1281 diis_step)
1282 CALL get_kpoint_info(kpoints_out, cell_to_index=cell_to_index)
1283 CALL prepare_wannier90_scf_mos(kpoints_out, kpoints_scf, matrix_s, matrix_ks, &
1284 cell_to_index, sab_nl, para_env, reused_scf_mos, &
1285 reuse_reason, aligned_blocks, aligned_max_size, &
1286 aligned_min_svalue)
1287 END IF
1288 IF (reused_scf_mos) THEN
1289 IF (output_unit > 0) THEN
1290 WRITE (output_unit, '(T2,A)') &
1291 "TREXIO| Reused SCF MO coefficients for the full k-point grid."
1292 IF (aligned_blocks > 0) THEN
1293 WRITE (output_unit, '(T2,A,I0,A,I0,A,ES10.3)') &
1294 "TREXIO| Ritz-stabilized ", aligned_blocks, &
1295 " degenerate SCF MO subspace(s); largest block has ", aligned_max_size, &
1296 " band(s), min metric eigenvalue ", aligned_min_svalue
1297 END IF
1298 END IF
1299 ELSE
1300 IF (output_unit > 0) THEN
1301 IF (reuse_scf_mos) THEN
1302 WRITE (output_unit, '(T2,A,A)') &
1303 "TREXIO| Could not reuse SCF MOs: ", trim(reuse_reason)
1304 END IF
1305 WRITE (output_unit, '(T2,A)') &
1306 "TREXIO| Diagonalizing the full k-point grid for export."
1307 END IF
1308 diis_step = .false.
1309 CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints_out, scf_env, scf_control, .false., &
1310 diis_step)
1311 END IF
1312 created = .true.
1313
1314 CALL timestop(handle)
1315#else
1316 mark_used(qs_env)
1317 mark_used(trexio_section)
1318 mark_used(do_kpoints)
1319 mark_used(kpoints_scf)
1320 NULLIFY (kpoints_out)
1321 created = .false.
1322#endif
1323
1324 END SUBROUTINE prepare_trexio_kpoint_grid
1325
1326! **************************************************************************************************
1327!> \brief Read a trexio file
1328!> \param qs_env the qs environment with all the info of the computation
1329!> \param trexio_filename the trexio filename without the extension
1330!> \param mo_set_trexio the MO set to read from the trexio file
1331!> \param energy_derivative the energy derivative to read from the trexio file
1332! **************************************************************************************************
1333 SUBROUTINE read_trexio(qs_env, trexio_filename, mo_set_trexio, energy_derivative)
1334 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1335 CHARACTER(len=*), INTENT(IN), OPTIONAL :: trexio_filename
1336 TYPE(mo_set_type), INTENT(OUT), DIMENSION(:), POINTER, OPTIONAL :: mo_set_trexio
1337 TYPE(dbcsr_p_type), INTENT(OUT), DIMENSION(:), POINTER, OPTIONAL :: energy_derivative
1338
1339#ifdef __TREXIO
1340
1341 CHARACTER(LEN=*), PARAMETER :: routinen = 'read_trexio'
1342
1343 INTEGER :: handle, output_unit, unit_de
1344 CHARACTER(len=default_path_length) :: filename, filename_de
1345 INTEGER(trexio_t) :: f ! The TREXIO file handle
1346 INTEGER(trexio_exit_code) :: rc ! TREXIO return code
1347
1348 LOGICAL :: ionode
1349
1350 CHARACTER(LEN=2) :: element_symbol
1351 CHARACTER(LEN=2), DIMENSION(:), ALLOCATABLE :: label
1352
1353 INTEGER :: ao_num, mo_num, nmo, nspins, ispin, nsgf, &
1354 save_cartesian, i, j, k, l, m, imo, ishell, &
1355 nshell, shell_num, nucleus_num, natoms, ikind, &
1356 iatom, nelectron, nrows, ncols, &
1357 row, col, row_size, col_size, &
1358 row_offset, col_offset, myprint
1359 INTEGER, DIMENSION(2) :: nmo_spin, electron_num
1360 INTEGER, DIMENSION(:), ALLOCATABLE :: mo_spin, shell_ang_mom, trexio_to_cp2k_ang_mom
1361
1362 REAL(kind=dp) :: zeff, maxocc
1363 REAL(kind=dp), DIMENSION(:), ALLOCATABLE :: mo_energy, mo_occupation, charge
1364 REAL(kind=dp), DIMENSION(:, :), ALLOCATABLE :: mo_coefficient, mos_sgf, coord, dedp, temp
1365 REAL(kind=dp), DIMENSION(:, :), POINTER :: data_block
1366
1367 TYPE(cp_logger_type), POINTER :: logger
1368 TYPE(cp_fm_type), POINTER :: mo_coeff_ref, mo_coeff_target
1369 TYPE(mp_para_env_type), POINTER :: para_env
1370 TYPE(dft_control_type), POINTER :: dft_control
1371 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1372 TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
1373 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1374 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1375 TYPE(dbcsr_iterator_type) :: iter
1376
1377 CALL timeset(routinen, handle)
1378
1379 NULLIFY (logger, mo_coeff_ref, mo_coeff_target, para_env, dft_control, matrix_s, kind_set, mos, particle_set)
1380
1381 logger => cp_get_default_logger()
1382 output_unit = cp_logger_get_default_io_unit(logger)
1383 myprint = logger%iter_info%print_level
1384
1385 cpassert(ASSOCIATED(qs_env))
1386
1387 ! get filename
1388 IF (.NOT. PRESENT(trexio_filename)) THEN
1389 filename = trim(logger%iter_info%project_name)//'-TREXIO.h5'
1390 filename_de = trim(logger%iter_info%project_name)//'-TREXIO.dEdP.dat'
1391 ELSE
1392 filename = trim(trexio_filename)//'.h5'
1393 filename_de = trim(trexio_filename)//'.dEdP.dat'
1394 END IF
1395
1396 CALL get_qs_env(qs_env, para_env=para_env)
1397 ionode = para_env%is_source()
1398
1399 ! Open the TREXIO file and check that we have the same molecule as in qs_env
1400 IF (ionode) THEN
1401 WRITE (output_unit, "((T2,A,A))") 'TREXIO| Opening file named ', trim(filename)
1402 f = trexio_open(filename, 'r', trexio_hdf5, rc)
1403 CALL trexio_error(rc)
1404
1405 IF (myprint > medium_print_level) THEN
1406 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading molecule information...'
1407 END IF
1408 rc = trexio_read_nucleus_num(f, nucleus_num)
1409 CALL trexio_error(rc)
1410
1411 IF (myprint > medium_print_level) THEN
1412 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading nuclear coordinates...'
1413 END IF
1414 ALLOCATE (coord(3, nucleus_num))
1415 rc = trexio_read_nucleus_coord(f, coord)
1416 CALL trexio_error(rc)
1417
1418 IF (myprint > medium_print_level) THEN
1419 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading nuclear labels...'
1420 END IF
1421 ALLOCATE (label(nucleus_num))
1422 rc = trexio_read_nucleus_label(f, label, 3)
1423 CALL trexio_error(rc)
1424
1425 IF (myprint > medium_print_level) THEN
1426 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading nuclear charges...'
1427 END IF
1428 ALLOCATE (charge(nucleus_num))
1429 rc = trexio_read_nucleus_charge(f, charge)
1430 CALL trexio_error(rc)
1431
1432 ! get the same info from qs_env
1433 CALL get_qs_env(qs_env, particle_set=particle_set, qs_kind_set=kind_set, natom=natoms)
1434
1435 ! check that we have the same number of atoms
1436 cpassert(nucleus_num == natoms)
1437
1438 DO iatom = 1, natoms
1439 ! compare the coordinates within a certain tolerance
1440 DO i = 1, 3
1441 cpassert(abs(coord(i, iatom) - particle_set(iatom)%r(i)) < 1.0e-6_dp)
1442 END DO
1443
1444 ! figure out the element symbol and to which kind_set entry this atomic_kind corresponds to
1445 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, element_symbol=element_symbol, kind_number=ikind)
1446 ! check that the element symbol is the same
1447 cpassert(trim(element_symbol) == trim(label(iatom)))
1448
1449 ! get the effective nuclear charge for this kind
1450 CALL get_qs_kind(kind_set(ikind), zeff=zeff)
1451 ! check that the nuclear charge is also the same
1452 cpassert(charge(iatom) == zeff)
1453 END DO
1454
1455 WRITE (output_unit, "((T2,A))") 'TREXIO| Molecule is the same as in qs_env'
1456 ! if we get here, we have the same molecule
1457 DEALLOCATE (coord)
1458 DEALLOCATE (label)
1459 DEALLOCATE (charge)
1460
1461 ! get info from trexio to map cp2k and trexio AOs
1462 rc = trexio_read_ao_cartesian(f, save_cartesian)
1463 CALL trexio_error(rc)
1464
1465 rc = trexio_read_ao_num(f, ao_num)
1466 CALL trexio_error(rc)
1467
1468 rc = trexio_read_basis_shell_num(f, shell_num)
1469 CALL trexio_error(rc)
1470 END IF
1471
1472 CALL para_env%bcast(save_cartesian, para_env%source)
1473 CALL para_env%bcast(ao_num, para_env%source)
1474 CALL para_env%bcast(shell_num, para_env%source)
1475
1476 IF (save_cartesian == 1) THEN
1477 cpabort('Reading Cartesian AOs is not yet supported.')
1478 END IF
1479
1480 ! check that the number of AOs and shells is the same
1481 CALL get_qs_env(qs_env, qs_kind_set=kind_set)
1482 CALL get_qs_kind_set(kind_set, nsgf=nsgf, nshell=nshell)
1483 cpassert(ao_num == nsgf)
1484 cpassert(shell_num == nshell)
1485
1486 ALLOCATE (shell_ang_mom(shell_num))
1487 shell_ang_mom(:) = 0
1488
1489 IF (ionode) THEN
1490 IF (myprint > medium_print_level) THEN
1491 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading shell angular momenta...'
1492 END IF
1493 rc = trexio_read_basis_shell_ang_mom(f, shell_ang_mom)
1494 CALL trexio_error(rc)
1495 END IF
1496
1497 CALL para_env%bcast(shell_ang_mom, para_env%source)
1498
1499 ! AO order map from TREXIO to CP2K convention
1500 ! from m = 0, +1, -1, +2, -2, ..., +l, -l of TREXIO
1501 ! to m = -l, -l+1, ..., 0, ..., l-1, l of CP2K
1502 ALLOCATE (trexio_to_cp2k_ang_mom(nsgf))
1503 i = 0
1504 DO ishell = 1, shell_num
1505 l = shell_ang_mom(ishell)
1506 DO k = 1, 2*l + 1
1507 m = (-1)**k*floor(real(k, kind=dp)/2.0_dp)
1508 trexio_to_cp2k_ang_mom(i + l + 1 + m) = i + k
1509 END DO
1510 i = i + 2*l + 1
1511 END DO
1512 cpassert(i == nsgf)
1513
1514 ! check whether we want to read MOs
1515 IF (PRESENT(mo_set_trexio)) THEN
1516 IF (output_unit > 1) THEN
1517 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading molecular orbitals...'
1518 END IF
1519
1520 ! at the moment, we assume that the basis set is the same
1521 ! first we read all arrays lengths we need from the trexio file
1522 IF (ionode) THEN
1523 rc = trexio_read_mo_num(f, mo_num)
1524 CALL trexio_error(rc)
1525
1526 rc = trexio_read_electron_up_num(f, electron_num(1))
1527 CALL trexio_error(rc)
1528
1529 rc = trexio_read_electron_dn_num(f, electron_num(2))
1530 CALL trexio_error(rc)
1531 END IF
1532
1533 ! broadcast information to all processors and allocate arrays
1534 CALL para_env%bcast(mo_num, para_env%source)
1535 CALL para_env%bcast(electron_num, para_env%source)
1536
1537 ! check that the number of MOs is the same
1538 CALL get_qs_env(qs_env, mos=mos, dft_control=dft_control)
1539 nspins = dft_control%nspins
1540 nmo_spin(:) = 0
1541 DO ispin = 1, nspins
1542 CALL get_mo_set(mos(ispin), nmo=nmo)
1543 nmo_spin(ispin) = nmo
1544 END DO
1545 cpassert(mo_num == sum(nmo_spin))
1546
1547 ALLOCATE (mo_coefficient(ao_num, mo_num))
1548 ALLOCATE (mo_energy(mo_num))
1549 ALLOCATE (mo_occupation(mo_num))
1550 ALLOCATE (mo_spin(mo_num))
1551
1552 mo_coefficient(:, :) = 0.0_dp
1553 mo_energy(:) = 0.0_dp
1554 mo_occupation(:) = 0.0_dp
1555 mo_spin(:) = 0
1556
1557 ! read the MOs info
1558 IF (ionode) THEN
1559 IF (myprint > medium_print_level) THEN
1560 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading MO coefficients...'
1561 END IF
1562 rc = trexio_read_mo_coefficient(f, mo_coefficient)
1563 CALL trexio_error(rc)
1564
1565 IF (myprint > medium_print_level) THEN
1566 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading MO energies...'
1567 END IF
1568 rc = trexio_read_mo_energy(f, mo_energy)
1569 CALL trexio_error(rc)
1570
1571 IF (myprint > medium_print_level) THEN
1572 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading MO occupations...'
1573 END IF
1574 rc = trexio_read_mo_occupation(f, mo_occupation)
1575 CALL trexio_error(rc)
1576
1577 IF (myprint > medium_print_level) THEN
1578 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading MO spins...'
1579 END IF
1580 rc = trexio_read_mo_spin(f, mo_spin)
1581 CALL trexio_error(rc)
1582 END IF
1583
1584 ! broadcast the data to all processors
1585 CALL para_env%bcast(mo_coefficient, para_env%source)
1586 CALL para_env%bcast(mo_energy, para_env%source)
1587 CALL para_env%bcast(mo_occupation, para_env%source)
1588 CALL para_env%bcast(mo_spin, para_env%source)
1589
1590 ! assume nspins and nmo_spin match the ones in the trexio file
1591 ! reorder magnetic quantum number
1592 DO ispin = 1, nspins
1593 ! global MOs index
1594 imo = (ispin - 1)*nmo_spin(1)
1595 ! get number of MOs for this spin
1596 nmo = nmo_spin(ispin)
1597 ! allocate local temp array to read MOs
1598 ALLOCATE (mos_sgf(nsgf, nmo))
1599 mos_sgf(:, :) = 0.0_dp
1600
1601 ! we need to reorder the MOs according to CP2K convention
1602 DO i = 1, nsgf
1603 mos_sgf(i, :) = mo_coefficient(trexio_to_cp2k_ang_mom(i), imo + 1:imo + nmo)
1604 END DO
1605
1606 IF (nspins == 1) THEN
1607 maxocc = 2.0_dp
1608 nelectron = electron_num(1) + electron_num(2)
1609 ELSE
1610 maxocc = 1.0_dp
1611 nelectron = electron_num(ispin)
1612 END IF
1613 ! the right number of active electrons per spin channel is initialized further down
1614 CALL allocate_mo_set(mo_set_trexio(ispin), nsgf, nmo, nelectron, 0.0_dp, maxocc, 0.0_dp)
1615
1616 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff_ref)
1617 CALL init_mo_set(mo_set_trexio(ispin), fm_ref=mo_coeff_ref, name="TREXIO MOs")
1618
1619 CALL get_mo_set(mo_set_trexio(ispin), mo_coeff=mo_coeff_target)
1620 DO j = 1, nmo
1621 ! make sure I copy the right spin channel
1622 cpassert(mo_spin(j) == ispin - 1)
1623 mo_set_trexio(ispin)%eigenvalues(j) = mo_energy(imo + j)
1624 mo_set_trexio(ispin)%occupation_numbers(j) = mo_occupation(imo + j)
1625 DO i = 1, nsgf
1626 CALL cp_fm_set_element(mo_coeff_target, i, j, mos_sgf(i, j))
1627 END DO
1628 END DO
1629
1630 DEALLOCATE (mos_sgf)
1631 END DO
1632
1633 DEALLOCATE (mo_coefficient)
1634 DEALLOCATE (mo_energy)
1635 DEALLOCATE (mo_occupation)
1636 DEALLOCATE (mo_spin)
1637
1638 END IF ! if MOs should be read
1639
1640 ! check whether we want to read derivatives
1641 IF (PRESENT(energy_derivative)) THEN
1642 IF (output_unit > 1) THEN
1643 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading energy derivatives...'
1644 END IF
1645
1646 ! Temporary solution: allocate here the energy derivatives matrix here
1647 ! assuming that nsgf is the same as the number read from the dEdP file
1648 ! TODO: once available in TREXIO, first read size and then allocate
1649 ! in the same way done for the MOs
1650 ALLOCATE (temp(nsgf, nsgf))
1651 temp(:, :) = 0.0_dp
1652
1653 ! check if file exists and open it
1654 IF (ionode) THEN
1655 IF (file_exists(filename_de)) THEN
1656 CALL open_file(file_name=filename_de, file_status="OLD", unit_number=unit_de)
1657 ELSE
1658 cpabort("Energy derivatives file "//trim(filename_de)//" not found")
1659 END IF
1660
1661 ! read the header and check everything is fine
1662 IF (myprint > medium_print_level) THEN
1663 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading header information...'
1664 END IF
1665 READ (unit_de, *) nrows, ncols
1666 IF (myprint > medium_print_level) THEN
1667 WRITE (output_unit, "((T2,A))") 'TREXIO| Check size of dEdP matrix...'
1668 END IF
1669 cpassert(nrows == nsgf)
1670 cpassert(ncols == nsgf)
1671
1672 ! read the data
1673 IF (myprint > medium_print_level) THEN
1674 WRITE (output_unit, "((T2,A))") 'TREXIO| Reading dEdP matrix...'
1675 END IF
1676 ! Read the data matrix
1677 DO i = 1, nrows
1678 READ (unit_de, *) (temp(i, j), j=1, ncols)
1679 END DO
1680
1681 CALL close_file(unit_number=unit_de)
1682 END IF
1683
1684 ! send data to all processes
1685 CALL para_env%bcast(temp, para_env%source)
1686
1687 ! Reshuffle
1688 ALLOCATE (dedp(nsgf, nsgf))
1689 dedp(:, :) = 0.0_dp
1690
1691 ! Reorder rows and columns according to trexio_to_cp2k_ang_mom mapping
1692 DO j = 1, nsgf
1693 DO i = 1, nsgf
1694 ! either this
1695 dedp(i, j) = temp(trexio_to_cp2k_ang_mom(i), trexio_to_cp2k_ang_mom(j))
1696 ! or this
1697 ! dEdP(cp2k_to_trexio_ang_mom(i), cp2k_to_trexio_ang_mom(j)) = temp(i, j)
1698 END DO
1699 END DO
1700
1701 DEALLOCATE (temp)
1702
1703 CALL get_qs_env(qs_env, matrix_s=matrix_s)
1704 DO ispin = 1, nspins
1705 ALLOCATE (energy_derivative(ispin)%matrix)
1706
1707 ! we use the overlap matrix as a template, copying it but removing the sparsity
1708 CALL dbcsr_copy(energy_derivative(ispin)%matrix, matrix_s(1)%matrix, &
1709 name='Energy Derivative', keep_sparsity=.false.)
1710 CALL dbcsr_set(energy_derivative(ispin)%matrix, 0.0_dp)
1711
1712 CALL dbcsr_iterator_start(iter, energy_derivative(ispin)%matrix)
1713 DO WHILE (dbcsr_iterator_blocks_left(iter))
1714 CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
1715 row_size=row_size, col_size=col_size, &
1716 row_offset=row_offset, col_offset=col_offset)
1717
1718 ! Copy data from array to block
1719 DO i = 1, row_size
1720 DO j = 1, col_size
1721 data_block(i, j) = dedp(row_offset + i - 1, col_offset + j - 1)
1722 END DO
1723 END DO
1724 END DO
1725 CALL dbcsr_iterator_stop(iter)
1726 END DO
1727
1728 DEALLOCATE (dedp)
1729 END IF ! finished reading energy derivatives
1730
1731 ! Clean up
1732 IF (ALLOCATED(shell_ang_mom)) DEALLOCATE (shell_ang_mom)
1733 IF (ALLOCATED(trexio_to_cp2k_ang_mom)) DEALLOCATE (trexio_to_cp2k_ang_mom)
1734
1735 ! Close the TREXIO file
1736 IF (ionode) THEN
1737 WRITE (output_unit, "((T2,A,A))") 'TREXIO| Closing file named ', trim(filename)
1738 rc = trexio_close(f)
1739 CALL trexio_error(rc)
1740 END IF
1741
1742 CALL timestop(handle)
1743
1744#else
1745 mark_used(qs_env)
1746 mark_used(trexio_filename)
1747 mark_used(mo_set_trexio)
1748 mark_used(energy_derivative)
1749 cpwarn('TREXIO support has not been enabled in this build.')
1750 cpabort('TREXIO Not Available')
1751#endif
1752
1753 END SUBROUTINE read_trexio
1754
1755#ifdef __TREXIO
1756! **************************************************************************************************
1757!> \brief Handles TREXIO errors
1758!> \param rc the TREXIO return code
1759! **************************************************************************************************
1760 SUBROUTINE trexio_error(rc)
1761 INTEGER(trexio_exit_code), INTENT(IN) :: rc
1762
1763 CHARACTER(LEN=128) :: err_msg
1764
1765 IF (rc /= trexio_success) THEN
1766 CALL trexio_string_of_error(rc, err_msg)
1767 cpabort('TREXIO Error: '//trim(err_msg))
1768 END IF
1769
1770 END SUBROUTINE trexio_error
1771
1772! **************************************************************************************************
1773!> \brief Computes the nuclear repulsion energy of a molecular system
1774!> \param particle_set the set of particles in the system
1775!> \param kind_set the set of qs_kinds in the system
1776!> \param e_nn the nuclear repulsion energy
1777! **************************************************************************************************
1778 SUBROUTINE nuclear_repulsion_energy(particle_set, kind_set, e_nn)
1779 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
1780 POINTER :: particle_set
1781 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
1782 POINTER :: kind_set
1783 REAL(kind=dp), INTENT(OUT) :: e_nn
1784
1785 INTEGER :: i, ikind, j, jkind, natoms
1786 REAL(kind=dp) :: r_ij, zeff_i, zeff_j
1787
1788 natoms = SIZE(particle_set)
1789 e_nn = 0.0_dp
1790 DO i = 1, natoms
1791 CALL get_atomic_kind(particle_set(i)%atomic_kind, kind_number=ikind)
1792 CALL get_qs_kind(kind_set(ikind), zeff=zeff_i)
1793 DO j = i + 1, natoms
1794 r_ij = norm2(particle_set(i)%r - particle_set(j)%r)
1795
1796 CALL get_atomic_kind(particle_set(j)%atomic_kind, kind_number=jkind)
1797 CALL get_qs_kind(kind_set(jkind), zeff=zeff_j)
1798
1799 e_nn = e_nn + zeff_i*zeff_j/r_ij
1800 END DO
1801 END DO
1802
1803 END SUBROUTINE nuclear_repulsion_energy
1804
1805! **************************************************************************************************
1806!> \brief Returns the normalization coefficient for a spherical GTO
1807!> \param l the angular momentum quantum number
1808!> \param expnt the exponent of the Gaussian function
1809!> \return ...
1810! **************************************************************************************************
1811 FUNCTION sgf_norm(l, expnt) RESULT(norm)
1812 INTEGER, INTENT(IN) :: l
1813 REAL(kind=dp), INTENT(IN) :: expnt
1814 REAL(kind=dp) :: norm
1815
1816 IF (l >= 0) THEN
1817 norm = sqrt(2**(2*l + 3)*fac(l + 1)*(2*expnt)**(l + 1.5)/(fac(2*l + 2)*sqrt(pi)))
1818 ELSE
1819 cpabort("The angular momentum should be >= 0!")
1820 END IF
1821
1822 END FUNCTION sgf_norm
1823
1824! **************************************************************************************************
1825!> \brief Computes a spherical to cartesian MO transformation (solid harmonics in reality)
1826!> \param mos_sgf the MO coefficients in spherical AO basis
1827!> \param particle_set the set of particles in the system
1828!> \param qs_kind_set the set of qs_kinds in the system
1829!> \param mos_cgf the transformed MO coefficients in Cartesian AO basis
1830! **************************************************************************************************
1831 SUBROUTINE spherical_to_cartesian_mo(mos_sgf, particle_set, qs_kind_set, mos_cgf)
1832 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: mos_sgf
1833 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
1834 POINTER :: particle_set
1835 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
1836 POINTER :: qs_kind_set
1837 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: mos_cgf
1838
1839 INTEGER :: iatom, icgf, ikind, iset, isgf, ishell, &
1840 lshell, ncgf, nmo, nset, nsgf
1841 INTEGER, DIMENSION(:), POINTER :: nshell
1842 INTEGER, DIMENSION(:, :), POINTER :: l
1843 TYPE(gto_basis_set_type), POINTER :: orb_basis_set
1844
1845 CALL get_qs_kind_set(qs_kind_set, ncgf=ncgf, nsgf=nsgf)
1846
1847 mos_cgf(:, :) = 0.0_dp
1848 nmo = SIZE(mos_sgf, 2)
1849
1850 ! Transform spherical MOs to Cartesian MOs
1851 icgf = 1
1852 isgf = 1
1853 DO iatom = 1, SIZE(particle_set)
1854 NULLIFY (orb_basis_set)
1855 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
1856 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
1857
1858 IF (ASSOCIATED(orb_basis_set)) THEN
1859 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1860 nset=nset, &
1861 nshell=nshell, &
1862 l=l)
1863 DO iset = 1, nset
1864 DO ishell = 1, nshell(iset)
1865 lshell = l(ishell, iset)
1866 CALL dgemm("T", "N", nco(lshell), nmo, nso(lshell), 1.0_dp, &
1867 orbtramat(lshell)%c2s, nso(lshell), &
1868 mos_sgf(isgf, 1), nsgf, 0.0_dp, &
1869 mos_cgf(icgf, 1), ncgf)
1870 icgf = icgf + nco(lshell)
1871 isgf = isgf + nso(lshell)
1872 END DO
1873 END DO
1874 ELSE
1875 ! assume atom without basis set
1876 cpabort("Unknown basis set type")
1877 END IF
1878 END DO ! iatom
1879
1880 END SUBROUTINE spherical_to_cartesian_mo
1881
1882! **************************************************************************************************
1883!> \brief Computes a cartesian to spherical MO transformation
1884!> \param mos_cgf the transformed MO coefficients in Cartesian AO basis
1885!> \param particle_set the set of particles in the system
1886!> \param qs_kind_set the set of qs_kinds in the system
1887!> \param mos_sgf the MO coefficients in spherical AO basis
1888! **************************************************************************************************
1889 SUBROUTINE cartesian_to_spherical_mo(mos_cgf, particle_set, qs_kind_set, mos_sgf)
1890 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: mos_cgf
1891 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
1892 POINTER :: particle_set
1893 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
1894 POINTER :: qs_kind_set
1895 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: mos_sgf
1896
1897 INTEGER :: iatom, icgf, ikind, iset, isgf, ishell, &
1898 lshell, ncgf, nmo, nset, nsgf
1899 INTEGER, DIMENSION(:), POINTER :: nshell
1900 INTEGER, DIMENSION(:, :), POINTER :: l
1901 TYPE(gto_basis_set_type), POINTER :: orb_basis_set
1902
1903 CALL get_qs_kind_set(qs_kind_set, ncgf=ncgf, nsgf=nsgf)
1904
1905 mos_sgf(:, :) = 0.0_dp
1906 nmo = SIZE(mos_cgf, 2)
1907
1908 ! Transform Cartesian MOs to spherical MOs
1909 icgf = 1
1910 isgf = 1
1911 DO iatom = 1, SIZE(particle_set)
1912 NULLIFY (orb_basis_set)
1913 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
1914 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
1915
1916 IF (ASSOCIATED(orb_basis_set)) THEN
1917 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1918 nset=nset, &
1919 nshell=nshell, &
1920 l=l)
1921 DO iset = 1, nset
1922 DO ishell = 1, nshell(iset)
1923 lshell = l(ishell, iset)
1924 CALL dgemm("N", "N", nso(lshell), nmo, nco(lshell), 1.0_dp, &
1925 orbtramat(lshell)%s2c, nso(lshell), &
1926 mos_cgf(icgf, 1), ncgf, 0.0_dp, &
1927 mos_sgf(isgf, 1), nsgf)
1928 icgf = icgf + nco(lshell)
1929 isgf = isgf + nso(lshell)
1930 END DO
1931 END DO
1932 ELSE
1933 ! assume atom without basis set
1934 cpabort("Unknown basis set type")
1935 END IF
1936 END DO ! iatom
1937
1938 END SUBROUTINE cartesian_to_spherical_mo
1939#endif
1940
1941END MODULE trexio_utils
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
subroutine, public sg_overlap(smat, l, pa, pb)
...
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)
...
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:49
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
character function, public dbcsr_get_matrix_type(matrix)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
DBCSR output in CP2K.
subroutine, public cp_dbcsr_write_sparse_matrix(sparse_matrix, before, after, qs_env, para_env, first_row, last_row, first_col, last_col, scale, output_unit, omit_headers, cartesian_basis)
...
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
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:504
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_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
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,...
subroutine, public cp_fm_set_element(matrix, irow_global, icol_global, alpha)
sets an element of a matrix
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
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public medium_print_level
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_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
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
real(kind=dp), parameter, public fourpi
real(kind=dp), dimension(0:maxfac), parameter, public fac
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public symmetrize_matrix(a, option)
Symmetrize the matrix a.
Definition mathlib.F:1206
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nco
integer, dimension(:), allocatable, public nso
Calculation of the spherical harmonics and the corresponding orbital transformation matrices.
type(orbtramat_type), dimension(:), pointer, public orbtramat
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.
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 init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
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
The module to read/write TREX IO files for interfacing CP2K with other programs.
subroutine, public write_trexio(qs_env, trexio_section, energy_derivative)
Write a trexio file.
subroutine, public read_trexio(qs_env, trexio_filename, mo_set_trexio, energy_derivative)
Read a trexio file.
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.