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