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

Generated by: LCOV version 2.0-1