LCOV - code coverage report
Current view: top level - src/xc - xc_gauxc_interface.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:7641cd9) Lines: 82.2 % 269 221
Test Date: 2026-05-25 07:16:39 Functions: 58.6 % 29 17

            Line data    Source code
       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              : #ifdef __GAUXC
       9              : #include "gauxc/gauxc_config.f"
      10              : #endif
      11              : 
      12              : #define GAUXC_RETURN_IF_ERROR(status) IF (status%status%code /= 0) RETURN
      13              : 
      14              : MODULE xc_gauxc_interface
      15              : 
      16              :    USE iso_c_binding, ONLY: &
      17              :       c_associated, &
      18              :       c_bool, &
      19              :       c_char, &
      20              :       c_double, &
      21              :       c_f_pointer, &
      22              :       c_int, &
      23              :       c_int32_t, &
      24              :       c_int64_t, &
      25              :       c_null_char, &
      26              :       c_null_ptr, &
      27              :       c_ptr, &
      28              :       c_size_t
      29              :    USE particle_types, ONLY: &
      30              :       particle_type
      31              :    USE qs_kind_types, ONLY: &
      32              :       get_qs_kind, &
      33              :       qs_kind_type
      34              :    USE cp_dbcsr_api, ONLY: &
      35              :       dbcsr_p_type
      36              : 
      37              : #ifdef __GAUXC
      38              : 
      39              :    USE kinds, ONLY: &
      40              :       default_path_length, &
      41              :       default_string_length, &
      42              :       dp
      43              :    USE physcon, ONLY: &
      44              :       bohr
      45              :    USE atomic_kind_types, ONLY: &
      46              :       atomic_kind_type, &
      47              :       get_atomic_kind, &
      48              :       get_atomic_kind_set
      49              :    USE qs_integral_utils, ONLY: &
      50              :       basis_set_list_setup
      51              :    USE basis_set_types, ONLY: &
      52              :       gto_basis_set_p_type, &
      53              :       gto_basis_set_type, &
      54              :       write_gto_basis_set
      55              :    USE periodic_table, ONLY: &
      56              :       get_ptable_info
      57              :    USE gauxc_status, ONLY: &
      58              :       gauxc_status_message, &
      59              :       gauxc_status_type
      60              :    USE gauxc_enums, ONLY: &
      61              :       gauxc_atomicgridsizedefault, &
      62              :       gauxc_executionspace, &
      63              :       gauxc_pruningscheme, &
      64              :       gauxc_radialquad
      65              :    USE gauxc_runtime_environment, ONLY: &
      66              :       gauxc_runtime_environment_delete, &
      67              :       gauxc_runtime_environment_new, &
      68              :       gauxc_runtime_environment_type
      69              :    USE gauxc_molecule, ONLY: &
      70              :       gauxc_delete, &
      71              :       gauxc_molecule_new_from_atoms, &
      72              :       gauxc_molecule_type
      73              :    USE gauxc_atom, ONLY: &
      74              :       gauxc_atom_type
      75              :    USE gauxc_basisset, ONLY: &
      76              :       gauxc_basisset_new, &
      77              :       gauxc_basisset_new_from_shells, &
      78              :       gauxc_basisset_type, &
      79              :       gauxc_delete
      80              :    USE gauxc_shell, ONLY: &
      81              :       gauxc_shell_type
      82              :    USE gauxc_molgrid, ONLY: &
      83              :       gauxc_delete, &
      84              :       gauxc_molgrid_new_default, &
      85              :       gauxc_molgrid_type
      86              :    USE gauxc_load_balancer, ONLY: &
      87              :       gauxc_delete, &
      88              :       gauxc_load_balancer_factory_get_instance, &
      89              :       gauxc_load_balancer_factory_new, &
      90              :       gauxc_load_balancer_factory_type, &
      91              :       gauxc_load_balancer_type
      92              :    USE gauxc_molecular_weights, ONLY: &
      93              :       gauxc_delete, &
      94              :       gauxc_get_instance, &
      95              :       gauxc_molecular_weights_factory_new, &
      96              :       gauxc_molecular_weights_factory_type, &
      97              :       gauxc_molecular_weights_modify_weights, &
      98              :       gauxc_molecular_weights_settings, &
      99              :       gauxc_molecular_weights_type
     100              :    USE gauxc_xc_functional, ONLY: &
     101              :       gauxc_delete, &
     102              :       gauxc_functional_from_string, &
     103              :       gauxc_functional_type
     104              :    USE gauxc_integrator, ONLY: &
     105              :       gauxc_delete, &
     106              :       gauxc_integrator_eval_exc_grad_rks, &
     107              :       gauxc_integrator_eval_exc_grad_uks, &
     108              :       gauxc_integrator_eval_exc_vxc_rks, &
     109              :       gauxc_integrator_eval_exc_vxc_uks, &
     110              :       gauxc_integrator_new, &
     111              :       gauxc_integrator_type
     112              : #ifdef GAUXC_HAS_ONEDFT
     113              :    USE gauxc_integrator, ONLY: &
     114              :       gauxc_integrator_eval_exc_grad_onedft_uks, &
     115              :       gauxc_integrator_eval_exc_vxc_onedft_uks
     116              :    USE OMP_LIB, ONLY: &
     117              :       omp_get_max_threads, &
     118              :       omp_set_num_threads
     119              : #endif
     120              : #ifdef GAUXC_HAS_HDF5
     121              :    USE gauxc_external_hdf5_write, ONLY: &
     122              :       gauxc_write_hdf5_record
     123              : #endif
     124              :    USE string_utilities, ONLY: &
     125              :       uppercase
     126              : #endif
     127              : 
     128              : #include "../base/base_uses.f90"
     129              : 
     130              :    IMPLICIT NONE
     131              :    PRIVATE
     132              : 
     133              : #ifndef __GAUXC
     134              : 
     135              :    ! The module still exists as an empty shell when compiling without GauXC.
     136              : 
     137              :    TYPE cp_gauxc_molecule_type
     138              :    END TYPE cp_gauxc_molecule_type
     139              : 
     140              :    TYPE cp_gauxc_basisset_type
     141              :       INTEGER :: max_l = -1
     142              :    END TYPE cp_gauxc_basisset_type
     143              : 
     144              :    TYPE cp_gauxc_grid_type
     145              :    END TYPE cp_gauxc_grid_type
     146              : 
     147              :    TYPE cp_gauxc_integrator_type
     148              :    END TYPE cp_gauxc_integrator_type
     149              : 
     150              :    TYPE cp_gauxc_status_type
     151              :    END TYPE cp_gauxc_status_type
     152              : 
     153              : #else
     154              : 
     155              :    ! TODO can we make the single fields private somehow?
     156              : 
     157              :    TYPE cp_gauxc_molecule_type
     158              :       TYPE(gauxc_molecule_type) :: molecule
     159              :    END TYPE cp_gauxc_molecule_type
     160              : 
     161              :    TYPE cp_gauxc_basisset_type
     162              :       TYPE(gauxc_basisset_type) :: basis
     163              :       INTEGER :: max_l = -1
     164              :    END TYPE cp_gauxc_basisset_type
     165              : 
     166              :    TYPE cp_gauxc_grid_type
     167              :       TYPE(gauxc_molgrid_type) :: grid
     168              :       TYPE(gauxc_load_balancer_type) :: lb
     169              :       TYPE(gauxc_load_balancer_factory_type) :: lbf
     170              :       TYPE(gauxc_molecular_weights_type) :: mw
     171              :       TYPE(gauxc_molecular_weights_factory_type) :: mwf
     172              :       TYPE(gauxc_runtime_environment_type) :: rt
     173              :       LOGICAL :: owns_rt = .FALSE.
     174              :    END TYPE cp_gauxc_grid_type
     175              : 
     176              :    TYPE cp_gauxc_integrator_type
     177              :       TYPE(gauxc_functional_type) :: func
     178              :       TYPE(gauxc_integrator_type) :: integrator
     179              :    END TYPE cp_gauxc_integrator_type
     180              : 
     181              :    TYPE cp_gauxc_status_type
     182              :       TYPE(gauxc_status_type) :: status
     183              :    END TYPE cp_gauxc_status_type
     184              : 
     185              :    TYPE(gauxc_runtime_environment_type) :: rt
     186              :    INTEGER :: rt_mpi_comm = -1
     187              :    LOGICAL :: rt_has_mpi_comm = .FALSE.
     188              : 
     189              : #endif
     190              : 
     191              :    TYPE cp_gauxc_xc_type
     192              :       REAL(c_double) :: exc
     193              :       REAL(c_double), DIMENSION(:, :), ALLOCATABLE :: vxc_scalar, vxc_zeta
     194              :    END TYPE cp_gauxc_xc_type
     195              : 
     196              :    TYPE cp_gauxc_xc_gradient_type
     197              :       REAL(c_double), ALLOCATABLE, DIMENSION(:) :: exc_grad
     198              :    END TYPE cp_gauxc_xc_gradient_type
     199              : 
     200              :    CHARACTER(len=*), PARAMETER :: no_gauxc_message = "Compile CP2K with GauXC to use this functionality!"
     201              : 
     202              :    PUBLIC :: &
     203              :       cp_gauxc_basisset_type, &
     204              :       cp_gauxc_grid_type, &
     205              :       cp_gauxc_integrator_type, &
     206              :       cp_gauxc_molecule_type, &
     207              :       cp_gauxc_status_type, &
     208              :       cp_gauxc_xc_gradient_type, &
     209              :       cp_gauxc_xc_type, &
     210              :       gauxc_check_status, &
     211              :       gauxc_compute_xc_gradient, &
     212              :       gauxc_compute_xc, &
     213              :       gauxc_create_basisset, &
     214              :       gauxc_create_grid, &
     215              :       gauxc_create_integrator, &
     216              :       gauxc_create_molecule, &
     217              :       gauxc_destroy_basisset, &
     218              :       gauxc_destroy_grid, &
     219              :       gauxc_destroy_integrator, &
     220              :       gauxc_destroy_molecule, &
     221              :       gauxc_finalize, &
     222              :       gauxc_init, &
     223              :       gauxc_write_basisset_hdf5, &
     224              :       gauxc_write_molecule_hdf5
     225              : CONTAINS
     226              : 
     227              : ! **************************************************************************************************
     228              : !> \brief ...
     229              : !> \param status ...
     230              : ! **************************************************************************************************
     231            0 :    SUBROUTINE print_gauxc_status_message(status)
     232              :       ! IMPORT :: c_ptr
     233              :       TYPE(cp_gauxc_status_type)                         :: status
     234              : 
     235              : #ifdef __GAUXC
     236            0 :       CHARACTER(kind=c_char), POINTER                    :: s(:)
     237              :       INTEGER                                            :: i
     238              : 
     239            0 :       WRITE (0, '(a,1x,i0)') "GauXC returned with status code", status%status%code
     240            0 :       IF (c_associated(status%status%message)) THEN
     241            0 :          WRITE (0, '(a)', ADVANCE='no') "GauXC status message: ["
     242              : 
     243            0 :          CALL c_f_pointer(status%status%message, s, [default_string_length])
     244            0 :          DO i = 1, SIZE(s)
     245            0 :             IF (s(i) == c_null_char) EXIT
     246            0 :             WRITE (0, '(A)', advance='no') s(i)
     247              :          END DO
     248              : 
     249            0 :          WRITE (0, '(a)') "]"
     250              :       ELSE
     251            0 :          WRITE (0, '(a)') "GauXC status message: [null]"
     252              :       END IF
     253              : #else
     254              :       MARK_USED(status)
     255              : #endif
     256            0 :    END SUBROUTINE print_gauxc_status_message
     257              : 
     258              : ! **************************************************************************************************
     259              : !> \brief ...
     260              : !> \param mpi_comm ...
     261              : !> \param status ...
     262              : ! **************************************************************************************************
     263        10112 :    SUBROUTINE gauxc_init(mpi_comm, status)
     264              :       INTEGER, INTENT(IN), OPTIONAL                      :: mpi_comm
     265              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     266              : 
     267              : #ifdef __GAUXC
     268              : #if defined(GAUXC_HAS_MPI) && defined(__parallel)
     269        10112 :       IF (PRESENT(mpi_comm)) THEN
     270        10112 :          rt = gauxc_runtime_environment_new(status%status, mpi_comm)
     271        10112 :          rt_mpi_comm = mpi_comm
     272        10112 :          rt_has_mpi_comm = .TRUE.
     273              :       ELSE
     274            0 :          rt = gauxc_runtime_environment_new(status%status)
     275            0 :          rt_mpi_comm = -1
     276            0 :          rt_has_mpi_comm = .FALSE.
     277              :       END IF
     278              : #else
     279              :       MARK_USED(mpi_comm)
     280              :       rt = gauxc_runtime_environment_new(status%status)
     281              :       rt_mpi_comm = -1
     282              :       rt_has_mpi_comm = .FALSE.
     283              : #endif
     284        10112 :       GAUXC_RETURN_IF_ERROR(status)
     285              : #else
     286              :       MARK_USED(mpi_comm)
     287              :       MARK_USED(status)
     288              : #endif
     289              :    END SUBROUTINE gauxc_init
     290              : 
     291              : ! **************************************************************************************************
     292              : !> \brief ...
     293              : !> \param status ...
     294              : ! **************************************************************************************************
     295        10112 :    SUBROUTINE gauxc_finalize(status)
     296              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     297              : 
     298              : #ifdef __GAUXC
     299        10112 :       CALL gauxc_runtime_environment_delete(status%status, rt)
     300        10112 :       GAUXC_RETURN_IF_ERROR(status)
     301        10112 :       rt_mpi_comm = -1
     302        10112 :       rt_has_mpi_comm = .FALSE.
     303              : #else
     304              :       MARK_USED(status)
     305              : #endif
     306              :    END SUBROUTINE gauxc_finalize
     307              : 
     308              : ! **************************************************************************************************
     309              : !> \brief ...
     310              : !> \param particle_set ...
     311              : !> \param status ...
     312              : !> \return ...
     313              : ! **************************************************************************************************
     314         1020 :    FUNCTION gauxc_create_molecule(particle_set, status) RESULT(res)
     315              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     316              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     317              :       TYPE(cp_gauxc_molecule_type)                       :: res
     318              : 
     319              : #ifdef __GAUXC
     320              :       CHARACTER(LEN=2)                                   :: element_symbol
     321              :       INTEGER                                            :: atomic_number, i, natoms
     322              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     323          510 :       TYPE(gauxc_atom_type), ALLOCATABLE, DIMENSION(:)   :: atoms
     324              : 
     325          510 :       natoms = SIZE(particle_set)
     326         1530 :       ALLOCATE (atoms(natoms))
     327              : 
     328         1726 :       DO i = 1, natoms
     329         1216 :          atomic_kind => particle_set(i)%atomic_kind
     330         1216 :          CALL get_atomic_kind(atomic_kind, element_symbol=element_symbol)
     331         1216 :          CALL get_ptable_info(element_symbol, number=atomic_number)
     332         1216 :          atoms(i)%atomic_number = INT(atomic_number, c_int64_t)
     333         1216 :          atoms(i)%x = REAL(particle_set(i)%r(1), c_double)
     334         1216 :          atoms(i)%y = REAL(particle_set(i)%r(2), c_double)
     335         1726 :          atoms(i)%z = REAL(particle_set(i)%r(3), c_double)
     336              :       END DO
     337              : 
     338          510 :       res%molecule = gauxc_molecule_new_from_atoms(status%status, atoms, INT(natoms, c_size_t))
     339          510 :       GAUXC_RETURN_IF_ERROR(status)
     340              : 
     341          510 :       DEALLOCATE (atoms)
     342              : #else
     343              :       MARK_USED(particle_set)
     344              :       MARK_USED(res)
     345              :       MARK_USED(status)
     346              :       CPABORT(no_gauxc_message)
     347              : #endif
     348         1020 :    END FUNCTION gauxc_create_molecule
     349              : 
     350              : ! **************************************************************************************************
     351              : !> \brief ...
     352              : !> \param qs_kind_set ...
     353              : !> \param particle_set ...
     354              : !> \param status ...
     355              : !> \return ...
     356              : ! **************************************************************************************************
     357         1020 :    FUNCTION gauxc_create_basisset(qs_kind_set, particle_set, status) RESULT(res)
     358              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
     359              :          POINTER                                         :: qs_kind_set
     360              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     361              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     362              :       TYPE(cp_gauxc_basisset_type)                       :: res
     363              : 
     364              : #ifdef __GAUXC
     365              :       INTEGER                                            :: iatom, ikind, iprim, iset, ishell, lval, &
     366              :                                                             nkind, npgf, nset, nshell, &
     367              :                                                             nshell_total, shell_index, natoms
     368              :       REAL(c_double), DIMENSION(3)                       :: shell_origin
     369              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     370          510 :       TYPE(gauxc_shell_type), ALLOCATABLE, DIMENSION(:)  :: shells
     371              :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     372              :       TYPE(gto_basis_set_type), POINTER                  :: gto_basis
     373              : 
     374          510 :       nkind = SIZE(qs_kind_set)
     375          510 :       natoms = SIZE(particle_set)
     376              : 
     377         2142 :       ALLOCATE (basis_set_list(nkind))
     378          510 :       CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
     379              : 
     380          510 :       nshell_total = 0
     381         1726 :       DO iatom = 1, natoms
     382         1216 :          atomic_kind => particle_set(iatom)%atomic_kind
     383         1216 :          CALL get_atomic_kind(atomic_kind, kind_number=ikind)
     384         1216 :          gto_basis => basis_set_list(ikind)%gto_basis_set
     385         1216 :          CPASSERT(ASSOCIATED(gto_basis))
     386              :          ! CALL write_gto_basis_set(gto_basis, 6, "–––––GAUXC-CREATE-BASISSET–––––")
     387         5234 :          nshell_total = nshell_total + SUM(gto_basis%nshell)
     388              :       END DO
     389              : 
     390         5386 :       ALLOCATE (shells(nshell_total))
     391              : 
     392         1726 :       shell_index = 0
     393         1726 :       res%max_l = -1
     394         1726 :       DO iatom = 1, natoms ! for each atom
     395         1216 :          atomic_kind => particle_set(iatom)%atomic_kind
     396         1216 :          CALL get_atomic_kind(atomic_kind, kind_number=ikind)
     397         1216 :          gto_basis => basis_set_list(ikind)%gto_basis_set
     398         1216 :          CPASSERT(ASSOCIATED(gto_basis))
     399              : 
     400         1216 :          shell_origin(1) = REAL(particle_set(iatom)%r(1), c_double)
     401         1216 :          shell_origin(2) = REAL(particle_set(iatom)%r(2), c_double)
     402         1216 :          shell_origin(3) = REAL(particle_set(iatom)%r(3), c_double)
     403              : 
     404         1216 :          nset = gto_basis%nset
     405         1216 :          CPASSERT(nset == SIZE(gto_basis%nshell))
     406         5234 :          DO iset = 1, nset ! for each shell group
     407         2292 :             nshell = gto_basis%nshell(iset)
     408         2292 :             npgf = gto_basis%npgf(iset) ! corresponds with nprim of gauxc
     409              : 
     410         7364 :             DO ishell = 1, gto_basis%nshell(iset) ! for each shell within the shell group
     411         3856 :                shell_index = shell_index + 1 ! global shell index, flattened over atoms and groups
     412         3856 :                lval = gto_basis%l(ishell, iset)
     413         3856 :                res%max_l = MAX(res%max_l, lval)
     414         3856 :                shells(shell_index)%l = INT(lval, c_int32_t)
     415              :                ! FIXME hardcoded true param
     416              :                ! pure=1: spherical Gaussians; pure=0: cartesian Gaussians
     417         3856 :                shells(shell_index)%pure = .TRUE._c_bool
     418         3856 :                shells(shell_index)%nprim = INT(npgf, c_int32_t)
     419        15424 :                shells(shell_index)%origin = shell_origin
     420              : 
     421        19092 :                DO iprim = 1, npgf
     422              :                   shells(shell_index)%exponents(iprim) = &
     423        12944 :                      REAL(gto_basis%zet(iprim, iset), c_double)
     424              :                   shells(shell_index)%coefficients(iprim) = &
     425              :                      REAL(gto_basis%norm_cgf(gto_basis%first_cgf(ishell, iset))* &
     426        16800 :                           gto_basis%gcc(iprim, ishell, iset), c_double)
     427              :                END DO
     428              :             END DO
     429              :          END DO
     430              :       END DO
     431              : 
     432              :       res%basis = gauxc_basisset_new_from_shells( &
     433              :                   status%status, &
     434              :                   shells, &
     435          510 :                   normalize=.FALSE.)
     436          510 :       GAUXC_RETURN_IF_ERROR(status)
     437              : 
     438          510 :       DEALLOCATE (shells)
     439          510 :       DEALLOCATE (basis_set_list)
     440              : 
     441              : #else
     442              :       MARK_USED(particle_set)
     443              :       MARK_USED(qs_kind_set)
     444              :       MARK_USED(res)
     445              :       MARK_USED(status)
     446              :       CPABORT(no_gauxc_message)
     447              : #endif
     448         1020 :    END FUNCTION gauxc_create_basisset
     449              : 
     450              : ! **************************************************************************************************
     451              : !> \brief ...
     452              : !> \param molecule ...
     453              : !> \param basis ...
     454              : !> \param grid_type ...
     455              : !> \param radial_quadrature ...
     456              : !> \param pruning_scheme ...
     457              : !> \param lb_exec_space ...
     458              : !> \param batch_size ...
     459              : !> \param status ...
     460              : !> \param mpi_comm optional communicator for a grid-local GauXC runtime
     461              : !> \return ...
     462              : ! **************************************************************************************************
     463          514 :    FUNCTION gauxc_create_grid( &
     464              :       molecule, &
     465              :       basis, &
     466              :       grid_type, &
     467              :       radial_quadrature, &
     468              :       pruning_scheme, &
     469              :       lb_exec_space, &
     470              :       batch_size, &
     471              :       status, &
     472          514 :       mpi_comm) RESULT(res)
     473              : 
     474              :       TYPE(cp_gauxc_molecule_type), INTENT(IN)           :: molecule
     475              :       TYPE(cp_gauxc_basisset_type), INTENT(in)           :: basis
     476              :       CHARACTER(len=*)               :: grid_type, lb_exec_space, &
     477              :                                         pruning_scheme, radial_quadrature
     478              :       INTEGER                                            :: batch_size
     479              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     480              :       INTEGER, INTENT(IN), OPTIONAL                      :: mpi_comm
     481              :       TYPE(cp_gauxc_grid_type)                           :: res
     482              : 
     483              : #ifdef __GAUXC
     484              :       INTEGER(c_int)                                     :: grid_type_local, int_exec_space_local, &
     485              :                                                             lb_exec_space_local, &
     486              :                                                             pruning_scheme_local, radial_quad_local
     487              : 
     488          514 :       grid_type_local = read_atomic_grid_size(grid_type)
     489          514 :       radial_quad_local = read_radial_quad(radial_quadrature)
     490          514 :       pruning_scheme_local = read_pruning_scheme(pruning_scheme)
     491          514 :       lb_exec_space_local = read_execution_space(lb_exec_space)
     492          514 :       int_exec_space_local = read_execution_space("host")
     493          514 :       res%owns_rt = .FALSE.
     494              : 
     495              : #if defined(GAUXC_HAS_MPI) && defined(__parallel)
     496          514 :       IF (PRESENT(mpi_comm)) THEN
     497              :          ! Reuse the global runtime when the requested communicator matches
     498              :          ! the communicator used during gauxc_init.
     499          514 :          IF (.NOT. rt_has_mpi_comm .OR. mpi_comm /= rt_mpi_comm) THEN
     500          228 :             res%rt = gauxc_runtime_environment_new(status%status, mpi_comm)
     501          228 :             GAUXC_RETURN_IF_ERROR(status)
     502              :             res%owns_rt = .TRUE.
     503              :          END IF
     504              :       END IF
     505              : #else
     506              :       MARK_USED(mpi_comm)
     507              : #endif
     508              : 
     509              :       res%grid = gauxc_molgrid_new_default( &
     510              :                  status%status, &
     511              :                  molecule%molecule, &
     512              :                  pruning_scheme_local, &
     513              :                  INT(batch_size, c_int64_t), &
     514              :                  radial_quad_local, &
     515          514 :                  grid_type_local)
     516          514 :       GAUXC_RETURN_IF_ERROR(status)
     517              : 
     518              :       res%lbf = gauxc_load_balancer_factory_new( &
     519              :                 status%status, &
     520          514 :                 lb_exec_space_local)
     521          514 :       GAUXC_RETURN_IF_ERROR(status)
     522              : 
     523          514 :       IF (res%owns_rt) THEN
     524              :          res%lb = gauxc_load_balancer_factory_get_instance( &
     525              :                   status%status, &
     526              :                   res%lbf, &
     527              :                   res%rt, &
     528              :                   molecule%molecule, &
     529              :                   res%grid, &
     530          228 :                   basis%basis)
     531              :       ELSE
     532              :          res%lb = gauxc_load_balancer_factory_get_instance( &
     533              :                   status%status, &
     534              :                   res%lbf, &
     535              :                   rt, &
     536              :                   molecule%molecule, &
     537              :                   res%grid, &
     538          286 :                   basis%basis)
     539              :       END IF
     540          514 :       GAUXC_RETURN_IF_ERROR(status)
     541              : 
     542              :       res%mwf = gauxc_molecular_weights_factory_new( &
     543              :                 status%status, &
     544          514 :                 int_exec_space_local)
     545          514 :       GAUXC_RETURN_IF_ERROR(status)
     546              : 
     547              :       res%mw = gauxc_get_instance( &
     548              :                status%status, &
     549          514 :                res%mwf)
     550          514 :       GAUXC_RETURN_IF_ERROR(status)
     551              : 
     552              :       CALL gauxc_molecular_weights_modify_weights( &
     553              :          status%status, &
     554              :          res%mw, &
     555          514 :          res%lb)
     556          514 :       GAUXC_RETURN_IF_ERROR(status)
     557              : 
     558              : #else
     559              :       MARK_USED(basis)
     560              :       MARK_USED(batch_size)
     561              :       MARK_USED(grid_type)
     562              :       MARK_USED(lb_exec_space)
     563              :       MARK_USED(mpi_comm)
     564              :       MARK_USED(molecule)
     565              :       MARK_USED(pruning_scheme)
     566              :       MARK_USED(radial_quadrature)
     567              :       MARK_USED(res)
     568              :       MARK_USED(status)
     569              :       CPABORT(no_gauxc_message)
     570              : #endif
     571         1028 :    END FUNCTION gauxc_create_grid
     572              : 
     573              : ! **************************************************************************************************
     574              : !> \brief ...
     575              : !> \param xc_functional_name ...
     576              : !> \param grid ...
     577              : !> \param int_exec_space ...
     578              : !> \param nspins ...
     579              : !> \param status ...
     580              : !> \return ...
     581              : ! **************************************************************************************************
     582          514 :    FUNCTION gauxc_create_integrator( &
     583              :       xc_functional_name, &
     584              :       grid, &
     585              :       int_exec_space, &
     586              :       nspins, &
     587          514 :       status) RESULT(res)
     588              : 
     589              :       CHARACTER(len=*), INTENT(IN)                       :: xc_functional_name, int_exec_space
     590              :       TYPE(cp_gauxc_grid_type), INTENT(IN)               :: grid
     591              :       INTEGER, INTENT(IN)                                :: nspins
     592              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     593              :       TYPE(cp_gauxc_integrator_type)                     :: res
     594              : 
     595              : #ifdef __GAUXC
     596              :       INTEGER(c_int)                                     :: int_exec_space_local
     597              :       LOGICAL(c_bool)                                    :: polarized
     598              : 
     599          514 :       polarized = (nspins == 2)
     600              :       res%func = gauxc_functional_from_string( &
     601              :                  status%status, &
     602              :                  xc_functional_name, &
     603         1028 :                  polarized)
     604          514 :       GAUXC_RETURN_IF_ERROR(status)
     605              : 
     606          514 :       int_exec_space_local = read_execution_space(int_exec_space)
     607              :       res%integrator = gauxc_integrator_new( &
     608              :                        status%status, &
     609              :                        res%func, &
     610              :                        grid%lb, &
     611          514 :                        int_exec_space_local)
     612          514 :       GAUXC_RETURN_IF_ERROR(status)
     613              : 
     614              : #else
     615              :       MARK_USED(grid)
     616              :       MARK_USED(int_exec_space)
     617              :       MARK_USED(nspins)
     618              :       MARK_USED(res)
     619              :       MARK_USED(status)
     620              :       MARK_USED(xc_functional_name)
     621              :       CPABORT(no_gauxc_message)
     622              : #endif
     623         1028 :    END FUNCTION gauxc_create_integrator
     624              : 
     625              : ! **************************************************************************************************
     626              : !> \brief ...
     627              : !> \param integrator ...
     628              : !> \param density_scalar ...
     629              : !> \param density_zeta ...
     630              : !> \param nspins ...
     631              : !> \param status ...
     632              : !> \param model ...
     633              : !> \return ...
     634              : ! **************************************************************************************************
     635         1020 :    FUNCTION gauxc_compute_xc( &
     636              :       integrator, &
     637         1020 :       density_scalar, &
     638          510 :       density_zeta, &
     639              :       nspins, &
     640              :       status, &
     641          510 :       model) RESULT(res)
     642              : 
     643              :       TYPE(cp_gauxc_integrator_type), INTENT(IN)         :: integrator
     644              :       ! Must be inout since we need to modify the matrix for some code paths
     645              :       REAL(c_double), DIMENSION(:, :)                    :: density_scalar
     646              :       REAL(c_double), DIMENSION(:, :), INTENT(IN), &
     647              :          OPTIONAL                                        :: density_zeta
     648              :       INTEGER, INTENT(IN)                                :: nspins
     649              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     650              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: model
     651              :       TYPE(cp_gauxc_xc_type)                             :: res
     652              : 
     653              : #ifdef __GAUXC
     654              :       CHARACTER(len=default_path_length)                 :: model_key
     655              :       LOGICAL                                            :: use_onedft
     656              : #ifdef GAUXC_HAS_ONEDFT
     657          510 :       REAL(c_double), ALLOCATABLE, DIMENSION(:, :)       :: density_zeta_zero
     658              :       INTEGER                                            :: omp_max_threads_restore
     659              : #endif
     660              : 
     661          510 :       use_onedft = .FALSE.
     662          510 :       IF (PRESENT(model)) THEN
     663          510 :          model_key = ADJUSTL(model)
     664          510 :          CALL uppercase(model_key)
     665          510 :          use_onedft = (TRIM(model_key) /= "" .AND. TRIM(model_key) /= "NONE")
     666              :       END IF
     667              : 
     668          510 :       IF (.NOT. ALLOCATED(res%vxc_scalar)) THEN
     669         2040 :          ALLOCATE (res%vxc_scalar, mold=density_scalar)
     670              :       ELSE
     671            0 :          CPASSERT(ALL(SHAPE(res%vxc_scalar) == SHAPE(density_scalar)))
     672              :       END IF
     673       140722 :       res%vxc_scalar = 0._dp
     674              : 
     675          510 :       IF (use_onedft) THEN
     676              : #ifndef GAUXC_HAS_ONEDFT
     677              :          CPABORT("GauXC lacks OneDFT support")
     678              : #else
     679              :          ! OneDFT may change the OpenMP team size for later parallel regions.
     680              :          ! Restore max threads only; omp_get_num_threads() is 1 here.
     681          486 :          omp_max_threads_restore = omp_get_max_threads()
     682          486 :          IF (.NOT. ALLOCATED(res%vxc_zeta)) THEN
     683         1944 :             ALLOCATE (res%vxc_zeta, mold=density_scalar)
     684              :          ELSE
     685            0 :             CPASSERT(ALL(SHAPE(res%vxc_zeta) == SHAPE(density_scalar)))
     686              :          END IF
     687       134666 :          res%vxc_zeta = 0._dp
     688              : 
     689          486 :          IF (nspins == 1) THEN
     690         1440 :             ALLOCATE (density_zeta_zero, mold=density_scalar)
     691          360 :             density_zeta_zero = 0._dp
     692              :             CALL gauxc_integrator_eval_exc_vxc_onedft_uks( &
     693              :                status%status, &
     694              :                integrator%integrator, &
     695              :                density_scalar, &
     696              :                density_zeta_zero, &
     697              :                TRIM(model), &
     698              :                res%exc, &
     699              :                res%vxc_scalar, &
     700       108000 :                res%vxc_zeta)
     701          360 :             DEALLOCATE (density_zeta_zero)
     702              :          ELSE
     703          126 :             CPASSERT(PRESENT(density_zeta))
     704              :             CALL gauxc_integrator_eval_exc_vxc_onedft_uks( &
     705              :                status%status, &
     706              :                integrator%integrator, &
     707              :                density_scalar, &
     708              :                density_zeta, &
     709              :                TRIM(model), &
     710              :                res%exc, &
     711              :                res%vxc_scalar, &
     712        53206 :                res%vxc_zeta)
     713              :          END IF
     714          486 :          CALL omp_set_num_threads(omp_max_threads_restore)
     715          486 :          GAUXC_RETURN_IF_ERROR(status)
     716          486 :          RETURN
     717              : #endif
     718              :       END IF
     719              : 
     720           24 :       IF (nspins == 1) THEN
     721              :          ! xmat factor 2 is applied by both CP2K and GauXC
     722              :          ! "unapply" it here to even things back out
     723              :          ! This is NOT necessary in the OneDFT branch
     724         6056 :          density_scalar = 0.5_dp*density_scalar
     725              :          CALL gauxc_integrator_eval_exc_vxc_rks( &
     726              :             status%status, &
     727              :             integrator%integrator, &
     728              :             density_scalar, &
     729              :             res%exc, &
     730         6056 :             res%vxc_scalar)
     731              :       ELSE
     732            0 :          CPASSERT(PRESENT(density_zeta))
     733              : 
     734            0 :          IF (.NOT. ALLOCATED(res%vxc_zeta)) THEN
     735            0 :             ALLOCATE (res%vxc_zeta, mold=density_zeta)
     736              :          ELSE
     737            0 :             CPASSERT(ALL(SHAPE(res%vxc_zeta) == SHAPE(density_scalar)))
     738              :          END IF
     739            0 :          res%vxc_zeta = 0._dp
     740              : 
     741              :          CALL gauxc_integrator_eval_exc_vxc_uks( &
     742              :             status%status, &
     743              :             integrator%integrator, &
     744              :             density_scalar, &
     745              :             density_zeta, &
     746              :             res%exc, &
     747              :             res%vxc_scalar, &
     748            0 :             res%vxc_zeta)
     749              :       END IF
     750           24 :       GAUXC_RETURN_IF_ERROR(status)
     751              : 
     752              : #else
     753              :       MARK_USED(integrator)
     754              :       MARK_USED(density_scalar)
     755              :       MARK_USED(density_zeta)
     756              :       MARK_USED(nspins)
     757              :       MARK_USED(status)
     758              :       MARK_USED(model)
     759              :       CPABORT(no_gauxc_message)
     760              : #endif
     761         1020 :    END FUNCTION gauxc_compute_xc
     762              : 
     763              : ! **************************************************************************************************
     764              : !> \brief ...
     765              : !> \param integrator ...
     766              : !> \param density_scalar ...
     767              : !> \param density_zeta ...
     768              : !> \param nspins ...
     769              : !> \param natom ...
     770              : !> \param status ...
     771              : !> \param model ...
     772              : !> \return ...
     773              : ! **************************************************************************************************
     774            8 :    FUNCTION gauxc_compute_xc_gradient( &
     775              :       integrator, &
     776            8 :       density_scalar, &
     777            4 :       density_zeta, &
     778              :       nspins, &
     779              :       natom, &
     780              :       status, &
     781            4 :       model) RESULT(res)
     782              : 
     783              :       TYPE(cp_gauxc_integrator_type), INTENT(IN)         :: integrator
     784              :       REAL(c_double), DIMENSION(:, :), INTENT(IN)        :: density_scalar
     785              :       REAL(c_double), DIMENSION(:, :), INTENT(IN), &
     786              :          OPTIONAL                                        :: density_zeta
     787              :       INTEGER, INTENT(IN)                                :: nspins, natom
     788              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     789              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: model
     790              :       TYPE(cp_gauxc_xc_gradient_type)                    :: res
     791              : 
     792              : #ifdef __GAUXC
     793              :       CHARACTER(len=default_path_length)                 :: model_key
     794              :       LOGICAL                                            :: use_onedft
     795              : #ifdef GAUXC_HAS_ONEDFT
     796            4 :       REAL(c_double), ALLOCATABLE, DIMENSION(:, :)       :: density_zeta_zero
     797              :       INTEGER                                            :: omp_max_threads_restore
     798              : #endif
     799              : 
     800           12 :       ALLOCATE (res%exc_grad(3*natom))
     801           40 :       res%exc_grad = 0._dp
     802              : 
     803            4 :       use_onedft = .FALSE.
     804            4 :       IF (PRESENT(model)) THEN
     805            4 :          model_key = ADJUSTL(model)
     806            4 :          CALL uppercase(model_key)
     807            4 :          use_onedft = (TRIM(model_key) /= "" .AND. TRIM(model_key) /= "NONE")
     808              :       END IF
     809              : 
     810              :       IF (use_onedft) THEN
     811              : #ifndef GAUXC_HAS_ONEDFT
     812              :          CPABORT("GauXC lacks OneDFT support")
     813              : #else
     814              :          ! OneDFT may change the OpenMP team size for later parallel regions.
     815              :          ! Restore max threads only; omp_get_num_threads() is 1 here.
     816            4 :          omp_max_threads_restore = omp_get_max_threads()
     817            4 :          IF (nspins == 1) THEN
     818           16 :             ALLOCATE (density_zeta_zero, mold=density_scalar)
     819            4 :             density_zeta_zero = 0._dp
     820              :             CALL gauxc_integrator_eval_exc_grad_onedft_uks( &
     821              :                status%status, &
     822              :                integrator%integrator, &
     823              :                density_scalar, &
     824              :                density_zeta_zero, &
     825              :                TRIM(model), &
     826         1848 :                res%exc_grad)
     827            4 :             DEALLOCATE (density_zeta_zero)
     828              :          ELSE
     829            0 :             CPASSERT(PRESENT(density_zeta))
     830              :             CALL gauxc_integrator_eval_exc_grad_onedft_uks( &
     831              :                status%status, &
     832              :                integrator%integrator, &
     833              :                density_scalar, &
     834              :                density_zeta, &
     835              :                TRIM(model), &
     836            0 :                res%exc_grad)
     837              :          END IF
     838            4 :          CALL omp_set_num_threads(omp_max_threads_restore)
     839            4 :          GAUXC_RETURN_IF_ERROR(status)
     840            4 :          RETURN
     841              : #endif
     842              :       END IF
     843              : 
     844            0 :       IF (nspins == 1) THEN
     845              :          CALL gauxc_integrator_eval_exc_grad_rks( &
     846              :             status%status, &
     847              :             integrator%integrator, &
     848              :             density_scalar, &
     849            0 :             res%exc_grad)
     850              :       ELSE
     851            0 :          CPASSERT(PRESENT(density_zeta))
     852              :          CALL gauxc_integrator_eval_exc_grad_uks( &
     853              :             status%status, &
     854              :             integrator%integrator, &
     855              :             density_scalar, &
     856              :             density_zeta, &
     857            0 :             res%exc_grad)
     858              :       END IF
     859            0 :       GAUXC_RETURN_IF_ERROR(status)
     860              : 
     861              : #else
     862              :       MARK_USED(density_scalar)
     863              :       MARK_USED(density_zeta)
     864              :       MARK_USED(res)
     865              :       MARK_USED(integrator)
     866              :       MARK_USED(model)
     867              :       MARK_USED(natom)
     868              :       MARK_USED(nspins)
     869              :       MARK_USED(status)
     870              :       CPABORT(no_gauxc_message)
     871              : #endif
     872            8 :    END FUNCTION gauxc_compute_xc_gradient
     873              : 
     874              : ! **************************************************************************************************
     875              : !> \brief ...
     876              : !> \param molecule ...
     877              : !> \param status ...
     878              : ! **************************************************************************************************
     879          510 :    SUBROUTINE gauxc_destroy_molecule(molecule, status)
     880              :       TYPE(cp_gauxc_molecule_type), INTENT(INOUT)        :: molecule
     881              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     882              : 
     883              : #ifdef __GAUXC
     884          510 :       CALL gauxc_delete(status%status, molecule%molecule)
     885          510 :       GAUXC_RETURN_IF_ERROR(status)
     886              : #else
     887              :       MARK_USED(molecule)
     888              :       MARK_USED(status)
     889              :       CPABORT(no_gauxc_message)
     890              : #endif
     891              :    END SUBROUTINE gauxc_destroy_molecule
     892              : 
     893              : ! **************************************************************************************************
     894              : !> \brief ...
     895              : !> \param basis ...
     896              : !> \param status ...
     897              : ! **************************************************************************************************
     898          510 :    SUBROUTINE gauxc_destroy_basisset(basis, status)
     899              :       TYPE(cp_gauxc_basisset_type), INTENT(INOUT)        :: basis
     900              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     901              : 
     902              : #ifdef __GAUXC
     903          510 :       CALL gauxc_delete(status%status, basis%basis)
     904          510 :       GAUXC_RETURN_IF_ERROR(status)
     905              : #else
     906              :       MARK_USED(basis)
     907              :       MARK_USED(status)
     908              :       CPABORT(no_gauxc_message)
     909              : #endif
     910              :    END SUBROUTINE gauxc_destroy_basisset
     911              : 
     912              : ! **************************************************************************************************
     913              : !> \brief ...
     914              : !> \param grid_result ...
     915              : !> \param status ...
     916              : ! **************************************************************************************************
     917          514 :    SUBROUTINE gauxc_destroy_grid(grid_result, status)
     918              :       TYPE(cp_gauxc_grid_type), INTENT(INOUT)            :: grid_result
     919              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     920              : 
     921              : #ifdef __GAUXC
     922          514 :       CALL gauxc_delete(status%status, grid_result%mw)
     923          514 :       GAUXC_RETURN_IF_ERROR(status)
     924          514 :       CALL gauxc_delete(status%status, grid_result%mwf)
     925          514 :       GAUXC_RETURN_IF_ERROR(status)
     926          514 :       CALL gauxc_delete(status%status, grid_result%lb)
     927          514 :       GAUXC_RETURN_IF_ERROR(status)
     928          514 :       CALL gauxc_delete(status%status, grid_result%lbf)
     929          514 :       GAUXC_RETURN_IF_ERROR(status)
     930          514 :       CALL gauxc_delete(status%status, grid_result%grid)
     931          514 :       GAUXC_RETURN_IF_ERROR(status)
     932          514 :       IF (grid_result%owns_rt) THEN
     933          228 :          CALL gauxc_runtime_environment_delete(status%status, grid_result%rt)
     934          228 :          GAUXC_RETURN_IF_ERROR(status)
     935          228 :          grid_result%owns_rt = .FALSE.
     936              :       END IF
     937              : #else
     938              :       MARK_USED(grid_result)
     939              :       MARK_USED(status)
     940              :       CPABORT(no_gauxc_message)
     941              : #endif
     942              :    END SUBROUTINE gauxc_destroy_grid
     943              : 
     944              : ! **************************************************************************************************
     945              : !> \brief ...
     946              : !> \param integrator_result ...
     947              : !> \param status ...
     948              : ! **************************************************************************************************
     949          514 :    SUBROUTINE gauxc_destroy_integrator(integrator_result, status)
     950              :       TYPE(cp_gauxc_integrator_type), INTENT(INOUT)      :: integrator_result
     951              :       TYPE(cp_gauxc_status_type), INTENT(OUT)            :: status
     952              : 
     953              : #ifdef __GAUXC
     954          514 :       CALL gauxc_delete(status%status, integrator_result%integrator)
     955          514 :       GAUXC_RETURN_IF_ERROR(status)
     956          514 :       CALL gauxc_delete(status%status, integrator_result%func)
     957          514 :       GAUXC_RETURN_IF_ERROR(status)
     958              : #else
     959              :       MARK_USED(integrator_result)
     960              :       MARK_USED(status)
     961              :       CPABORT(no_gauxc_message)
     962              : #endif
     963              :    END SUBROUTINE gauxc_destroy_integrator
     964              : 
     965              : ! **************************************************************************************************
     966              : !> \brief Checks gauxc status and prints error message before aborting
     967              : !> \param status the gauxc status to check
     968              : ! **************************************************************************************************
     969        24834 :    SUBROUTINE gauxc_check_status(status)
     970              :       TYPE(cp_gauxc_status_type), INTENT(IN)                :: status
     971              : 
     972              : #ifdef __GAUXC
     973        24834 :       IF (status%status%code /= 0) THEN
     974            0 :          CALL print_gauxc_status_message(status)
     975            0 :          CPABORT("GauXC returned with non-zero status code")
     976              :       END IF
     977              : #else
     978              :       MARK_USED(status)
     979              : #endif
     980        24834 :    END SUBROUTINE gauxc_check_status
     981              : 
     982              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     983              : ! From here on, it's private helpers !
     984              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     985              : 
     986              : #ifdef __GAUXC
     987              : 
     988              : ! **************************************************************************************************
     989              : !> \brief ...
     990              : !> \param spec ...
     991              : !> \return ...
     992              : ! **************************************************************************************************
     993         1542 :    PURE FUNCTION read_execution_space(spec) RESULT(val)
     994              :       CHARACTER(len=*), INTENT(IN)                       :: spec
     995              :       INTEGER(c_int)                                     :: val
     996              : 
     997         1542 :       CHARACTER(len=LEN(spec))                           :: spec_upper
     998              : 
     999         1542 :       spec_upper = spec
    1000         1542 :       CALL uppercase(spec_upper)
    1001              : 
    1002              :       SELECT CASE (spec_upper)
    1003              :       CASE ("HOST")
    1004            0 :          val = gauxc_executionspace%host
    1005              :       CASE ("DEVICE")
    1006            0 :          val = gauxc_executionspace%device
    1007              :       CASE DEFAULT
    1008         1542 :          val = gauxc_executionspace%host
    1009              :       END SELECT
    1010         1542 :    END FUNCTION read_execution_space
    1011              : 
    1012              : ! **************************************************************************************************
    1013              : !> \brief ...
    1014              : !> \param spec ...
    1015              : !> \return ...
    1016              : ! **************************************************************************************************
    1017          514 :    PURE FUNCTION read_atomic_grid_size(spec) RESULT(val)
    1018              :       CHARACTER(len=*), INTENT(IN)                       :: spec
    1019              :       INTEGER(c_int)                                     :: val
    1020              : 
    1021          514 :       CHARACTER(len=LEN(spec))                           :: spec_upper
    1022              : 
    1023          514 :       spec_upper = spec
    1024          514 :       CALL uppercase(spec_upper)
    1025              : 
    1026              :       SELECT CASE (spec_upper)
    1027              :       CASE ("FINE")
    1028            0 :          val = gauxc_atomicgridsizedefault%finegrid
    1029              :       CASE ("ULTRAFINE")
    1030            0 :          val = gauxc_atomicgridsizedefault%ultrafinegrid
    1031              :       CASE ("SUPERFINE")
    1032           42 :          val = gauxc_atomicgridsizedefault%superfinegrid
    1033              :       CASE ("GM3")
    1034            0 :          val = gauxc_atomicgridsizedefault%gm3
    1035              :       CASE ("GM5")
    1036            0 :          val = gauxc_atomicgridsizedefault%gm5
    1037              :       CASE DEFAULT
    1038          514 :          val = gauxc_atomicgridsizedefault%finegrid
    1039              :       END SELECT
    1040          514 :    END FUNCTION read_atomic_grid_size
    1041              : 
    1042              : ! **************************************************************************************************
    1043              : !> \brief ...
    1044              : !> \param spec ...
    1045              : !> \return ...
    1046              : ! **************************************************************************************************
    1047          514 :    PURE FUNCTION read_radial_quad(spec) RESULT(val)
    1048              :       CHARACTER(len=*), INTENT(IN)                       :: spec
    1049              :       INTEGER(c_int)                                     :: val
    1050              : 
    1051          514 :       CHARACTER(len=LEN(spec))                           :: spec_upper
    1052              : 
    1053          514 :       spec_upper = spec
    1054          514 :       CALL uppercase(spec_upper)
    1055              : 
    1056              :       SELECT CASE (spec_upper)
    1057              :       CASE ("BECKE")
    1058          514 :          val = gauxc_radialquad%becke
    1059              :       CASE ("MURAKNOWLES")
    1060          514 :          val = gauxc_radialquad%mura_knowles
    1061              :       CASE ("TREUTLERAHLRICHS")
    1062            0 :          val = gauxc_radialquad%treutler_ahlrichs
    1063              :       CASE ("MURRAYHANDYLAMING")
    1064            0 :          val = gauxc_radialquad%murray_handy_laming
    1065              :       CASE DEFAULT
    1066          514 :          val = gauxc_radialquad%mura_knowles
    1067              :       END SELECT
    1068          514 :    END FUNCTION read_radial_quad
    1069              : 
    1070              : ! **************************************************************************************************
    1071              : !> \brief ...
    1072              : !> \param spec ...
    1073              : !> \return ...
    1074              : ! **************************************************************************************************
    1075          514 :    PURE FUNCTION read_pruning_scheme(spec) RESULT(val)
    1076              :       CHARACTER(len=*), INTENT(IN)                       :: spec
    1077              :       INTEGER(c_int)                                     :: val
    1078              : 
    1079          514 :       CHARACTER(len=LEN(spec))                           :: spec_upper
    1080              : 
    1081          514 :       spec_upper = spec
    1082          514 :       CALL uppercase(spec_upper)
    1083              : 
    1084              :       SELECT CASE (spec_upper)
    1085              :       CASE ("UNPRUNED")
    1086          472 :          val = gauxc_pruningscheme%unpruned
    1087              :       CASE ("ROBUST")
    1088          472 :          val = gauxc_pruningscheme%robust
    1089              :       CASE ("TREUTLER")
    1090            0 :          val = gauxc_pruningscheme%treutler
    1091              :       CASE DEFAULT
    1092          514 :          val = gauxc_pruningscheme%robust
    1093              :       END SELECT
    1094          514 :    END FUNCTION read_pruning_scheme
    1095              : 
    1096              : #endif
    1097              : 
    1098              : ! **************************************************************************************************
    1099              : !> \brief Write molecule data to HDF5 file for debugging
    1100              : !> \param molecule ...
    1101              : !> \param output_path ...
    1102              : !> \param filename ...
    1103              : !> \param dataset ...
    1104              : !> \param status ...
    1105              : ! **************************************************************************************************
    1106            0 :    SUBROUTINE gauxc_write_molecule_hdf5(molecule, output_path, filename, dataset, status)
    1107              :       TYPE(cp_gauxc_molecule_type), INTENT(IN)           :: molecule
    1108              :       CHARACTER(len=*), INTENT(IN)                       :: output_path, filename, dataset
    1109              :       TYPE(cp_gauxc_status_type), INTENT(INOUT)          :: status
    1110              : 
    1111              : #if defined(__GAUXC) && defined(GAUXC_HAS_HDF5)
    1112              :       CHARACTER(len=default_path_length)                 :: full_path
    1113              : 
    1114              :       full_path = TRIM(output_path)//"/"//TRIM(filename)
    1115              :       CALL gauxc_write_hdf5_record(status%status, molecule%molecule, full_path, dataset)
    1116              : #else
    1117              :       MARK_USED(molecule)
    1118              :       MARK_USED(output_path)
    1119              :       MARK_USED(filename)
    1120              :       MARK_USED(dataset)
    1121              :       MARK_USED(status)
    1122            0 :       CPABORT("GauXC HDF5 output requires GauXC to be built with HDF5 support.")
    1123              : #endif
    1124            0 :    END SUBROUTINE gauxc_write_molecule_hdf5
    1125              : 
    1126              : ! **************************************************************************************************
    1127              : !> \brief Write basis set data to HDF5 file for debugging
    1128              : !> \param basis ...
    1129              : !> \param output_path ...
    1130              : !> \param filename ...
    1131              : !> \param dataset ...
    1132              : !> \param status ...
    1133              : ! **************************************************************************************************
    1134            0 :    SUBROUTINE gauxc_write_basisset_hdf5(basis, output_path, filename, dataset, status)
    1135              :       TYPE(cp_gauxc_basisset_type), INTENT(IN)           :: basis
    1136              :       CHARACTER(len=*), INTENT(IN)                       :: output_path, filename, dataset
    1137              :       TYPE(cp_gauxc_status_type), INTENT(INOUT)          :: status
    1138              : 
    1139              : #if defined(__GAUXC) && defined(GAUXC_HAS_HDF5)
    1140              :       CHARACTER(len=default_path_length)                 :: full_path
    1141              : 
    1142              :       full_path = TRIM(output_path)//"/"//TRIM(filename)
    1143              :       CALL gauxc_write_hdf5_record(status%status, basis%basis, full_path, dataset)
    1144              : #else
    1145              :       MARK_USED(basis)
    1146              :       MARK_USED(output_path)
    1147              :       MARK_USED(filename)
    1148              :       MARK_USED(dataset)
    1149              :       MARK_USED(status)
    1150            0 :       CPABORT("GauXC HDF5 output requires GauXC to be built with HDF5 support.")
    1151              : #endif
    1152            0 :    END SUBROUTINE gauxc_write_basisset_hdf5
    1153              : 
    1154            0 : END MODULE xc_gauxc_interface
        

Generated by: LCOV version 2.0-1