mirror of
https://github.com/TREX-CoE/trexio.git
synced 2025-03-04 06:10:23 +01:00
Merge pull request #168 from TREX-CoE/det-checks
Fix text backend for determinants + check consistency of determinants
This commit is contained in:
commit
ccb9bf8587
2
.github/workflows/actions.yml
vendored
2
.github/workflows/actions.yml
vendored
@ -71,7 +71,7 @@ jobs:
|
||||
run: make -j2
|
||||
|
||||
- name: check TREXIO
|
||||
run: make -j2 check
|
||||
run: make -j2 check # Non-parallel run
|
||||
|
||||
- name: Archive test log file
|
||||
if: failure()
|
||||
|
@ -43,6 +43,7 @@ AC_SUBST([UNAME])
|
||||
|
||||
# Fortran API [default: --with-fortran], do not disable in the dev mode
|
||||
AC_PROG_FC
|
||||
|
||||
AC_ARG_WITH(fortran, [AS_HELP_STRING([--without-fortran],[do not test and install the Fortran API])], ok=$withval, ok=yes)
|
||||
AS_IF([test "$ok" = "yes"],[
|
||||
AC_FC_FREEFORM
|
||||
@ -52,9 +53,9 @@ AS_IF([test "$ok" = "yes"],[
|
||||
|
||||
# Specific options required with some compilers
|
||||
AS_CASE([$FC],
|
||||
[*gfortran*], [FCFLAGS="$FCFLAGS -fPIC"],
|
||||
[*flang*], [FCFLAGS="$FCFLAGS -fPIC"],
|
||||
[*ifort*], [FCFLAGS="$FCFLAGS -fPIC"],
|
||||
[*gfortran*], [FCFLAGS="$FCFLAGS -g -fPIC"],
|
||||
[*flang*], [FCFLAGS="$FCFLAGS -g -fPIC"],
|
||||
[*ifort*], [FCFLAGS="$FCFLAGS -g -fPIC"],
|
||||
[])
|
||||
|
||||
])
|
||||
|
@ -6,6 +6,62 @@ import trexio
|
||||
from benzene_data import *
|
||||
|
||||
|
||||
# this function is copied from the trexio-tools github repository (BSD-3 license):
|
||||
# https://github.com/TREX-CoE/trexio_tools/blob/master/src/trexio_tools/group_tools/determinant.py
|
||||
def to_determinant_list(orbital_list: list, int64_num: int) -> list:
|
||||
"""
|
||||
Convert a list of occupied orbitals from the `orbital_list`
|
||||
into a list of Slater determinants (in their bit string representation).
|
||||
|
||||
Orbitals in the `orbital_list` should be 0-based, namely the lowest orbital has index 0, not 1.
|
||||
|
||||
int64_num is the number of 64-bit integers needed to represent a Slater determinant bit string.
|
||||
It depends on the number of molecular orbitals as follows: int64_num = int((mo_num-1)/64) + 1
|
||||
"""
|
||||
|
||||
if not isinstance(orbital_list, list):
|
||||
raise TypeError(f"orbital_list should be a list, not {type(orbital_list)}")
|
||||
|
||||
det_list = []
|
||||
bitfield = 0
|
||||
shift = 0
|
||||
|
||||
# since orbital indices are 0-based but the code below works for 1-based --> increment the input indices by +1
|
||||
orb_list_upshifted = [ orb+1 for orb in orbital_list]
|
||||
|
||||
# orbital list has to be sorted in increasing order for the bitfields to be set correctly
|
||||
orb_list_sorted = sorted(orb_list_upshifted)
|
||||
|
||||
for orb in orb_list_sorted:
|
||||
|
||||
if orb-shift > 64:
|
||||
# this removes the 0 bit from the beginning of the bitfield
|
||||
bitfield = bitfield >> 1
|
||||
# append a bitfield to the list
|
||||
det_list.append(bitfield)
|
||||
bitfield = 0
|
||||
|
||||
modulo = int((orb-1)/64)
|
||||
shift = modulo*64
|
||||
bitfield |= (1 << (orb-shift))
|
||||
|
||||
# this removes the 0 bit from the beginning of the bitfield
|
||||
bitfield = bitfield >> 1
|
||||
det_list.append(bitfield)
|
||||
#print('Popcounts: ', [bin(d).count('1') for d in det_list)
|
||||
#print('Bitfields: ', [bin(d) for d in det_list])
|
||||
|
||||
bitfield_num = len(det_list)
|
||||
if bitfield_num > int64_num:
|
||||
raise Exception(f'Number of bitfields {bitfield_num} cannot be more than the int64_num {int64_num}.')
|
||||
if bitfield_num < int64_num:
|
||||
for _ in range(int64_num - bitfield_num):
|
||||
print("Appending an empty bitfield.")
|
||||
det_list.append(0)
|
||||
|
||||
return det_list
|
||||
|
||||
|
||||
def clean(back_end, filename):
|
||||
"""Remove test files."""
|
||||
if back_end == trexio.TREXIO_HDF5:
|
||||
@ -206,16 +262,36 @@ class TestIO:
|
||||
"""Write CI determinants and coefficients."""
|
||||
self.open()
|
||||
# write mo_num (needed later to write determinants)
|
||||
trexio.write_mo_num(self.test_file, mo_num)
|
||||
MO_NUM_TEST = 100
|
||||
trexio.write_mo_num(self.test_file, MO_NUM_TEST)
|
||||
# get the number of bit-strings per spin component
|
||||
INT64_NUM_TEST = int((MO_NUM_TEST-1)/64) + 1
|
||||
int_num = trexio.get_int64_num(self.test_file)
|
||||
assert int_num == int64_num
|
||||
assert int_num == INT64_NUM_TEST
|
||||
# write the number of up and down electrons
|
||||
trexio.write_electron_up_num(self.test_file, 4)
|
||||
trexio.write_electron_dn_num(self.test_file, 3)
|
||||
# orbital lists
|
||||
orb_list_up = [0,1,2,3]
|
||||
orb_list_dn = [0,1,2]
|
||||
|
||||
# data to write
|
||||
DET_NUM_TEST = 100
|
||||
det_up = to_determinant_list(orb_list_up, INT64_NUM_TEST)
|
||||
det_dn = to_determinant_list(orb_list_dn, INT64_NUM_TEST)
|
||||
|
||||
det_list = []
|
||||
coeff_list = []
|
||||
for i in range(DET_NUM_TEST):
|
||||
det_list.append(det_up + det_dn)
|
||||
coeff_list.append(3.14 + float(i))
|
||||
|
||||
# write the data for the ground state
|
||||
offset = 0
|
||||
trexio.write_state_id(self.test_file, 0)
|
||||
trexio.write_determinant_list(self.test_file, offset, det_num, dets)
|
||||
trexio.write_determinant_list(self.test_file, offset, DET_NUM_TEST, det_list)
|
||||
assert trexio.has_determinant_list(self.test_file)
|
||||
trexio.write_determinant_coefficient(self.test_file, offset, det_num, coeffs)
|
||||
trexio.write_determinant_coefficient(self.test_file, offset, DET_NUM_TEST, coeff_list)
|
||||
assert trexio.has_determinant_coefficient(self.test_file)
|
||||
# manually check the consistency between coefficient_size and number of determinants
|
||||
assert trexio.read_determinant_coefficient_size(self.test_file) == trexio.read_determinant_num(self.test_file)
|
||||
@ -350,26 +426,6 @@ class TestIO:
|
||||
if self.test_file.isOpen:
|
||||
self.test_file.close()
|
||||
|
||||
def test_determinant_read(self):
|
||||
"""Read the CI determinants."""
|
||||
self.open(mode='r')
|
||||
# read determinants (list of ints and float coefficients)
|
||||
buf_size = 100
|
||||
offset_file = 0
|
||||
# read full buf_size (i.e. the one that does not reach EOF)
|
||||
dets_np, read_buf_size, eof = trexio.read_determinant_list(self.test_file, offset_file, buf_size)
|
||||
#print(f'First complete read of determinant list: {read_buf_size}')
|
||||
assert not eof
|
||||
assert read_buf_size == buf_size
|
||||
assert dets_np[0][0] == 0
|
||||
assert dets_np[read_buf_size-1][int64_num*2-1] == read_buf_size * int64_num * 2- 1
|
||||
|
||||
coefficients_np, read_buf_size, eof = trexio.read_determinant_coefficient(self.test_file, offset_file, buf_size)
|
||||
#print(f'First complete read of determinant coefficients: {read_buf_size}')
|
||||
assert not eof
|
||||
assert read_buf_size == buf_size
|
||||
if self.test_file.isOpen:
|
||||
self.test_file.close()
|
||||
|
||||
def test_array_str_read(self):
|
||||
"""Read an array of strings."""
|
||||
|
@ -32,7 +32,7 @@ with open('../../trex.json','r') as f:
|
||||
res += line.rstrip()+'\n'
|
||||
res += "*/"
|
||||
return res
|
||||
#+end_src
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: trex_json
|
||||
:results:
|
||||
@ -470,6 +470,7 @@ __trexio_path__ = None
|
||||
| ~TREXIO_INVALID_STATE~ | 35 | 'Inconsistent state of the file' |
|
||||
| ~TREXIO_VERSION_PARSING_ISSUE~ | 36 | 'Failed to parse package_version' |
|
||||
| ~TREXIO_PHASE_CHANGE~ | 37 | 'The function succeeded with a change of sign' |
|
||||
| ~TREXIO_INVALID_MO_INDEX~ | 38 | 'Invalid MO index' |
|
||||
|
||||
# We need to force Emacs not to indent the Python code:
|
||||
# -*- org-src-preserve-indentation: t
|
||||
@ -554,6 +555,7 @@ return '\n'.join(result)
|
||||
#define TREXIO_INVALID_STATE ((trexio_exit_code) 35)
|
||||
#define TREXIO_VERSION_PARSING_ISSUE ((trexio_exit_code) 36)
|
||||
#define TREXIO_PHASE_CHANGE ((trexio_exit_code) 37)
|
||||
#define TREXIO_INVALID_MO_INDEX ((trexio_exit_code) 38)
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle prefix_fortran.f90 :exports none
|
||||
@ -596,6 +598,7 @@ return '\n'.join(result)
|
||||
integer(trexio_exit_code), parameter :: TREXIO_INVALID_STATE = 35
|
||||
integer(trexio_exit_code), parameter :: TREXIO_VERSION_PARSING_ISSUE = 36
|
||||
integer(trexio_exit_code), parameter :: TREXIO_PHASE_CHANGE = 37
|
||||
integer(trexio_exit_code), parameter :: TREXIO_INVALID_MO_INDEX = 38
|
||||
#+end_src
|
||||
|
||||
#+begin_src python :tangle prefix_python.py :exports none
|
||||
@ -639,6 +642,7 @@ return '\n'.join(result)
|
||||
TREXIO_INVALID_STATE = 35
|
||||
TREXIO_VERSION_PARSING_ISSUE = 36
|
||||
TREXIO_PHASE_CHANGE = 37
|
||||
TREXIO_INVALID_MO_INDEX = 38
|
||||
#+end_src
|
||||
:end:
|
||||
|
||||
@ -5182,11 +5186,7 @@ end interface
|
||||
integer(c_int32_t), intent(in), value :: max_str_len
|
||||
character(len=*), intent(in) :: str
|
||||
|
||||
character(len=len_trim(str)+1) :: str_c
|
||||
|
||||
str_c = trim(str) // c_null_char
|
||||
|
||||
trexio_write_$group_str$ = trexio_write_$group_str$_c(trex_file, str_c, max_str_len)
|
||||
trexio_write_$group_str$ = trexio_write_$group_str$_c(trex_file, trim(str) // c_null_char, max_str_len)
|
||||
|
||||
end function trexio_write_$group_str$
|
||||
#+end_src
|
||||
@ -5398,7 +5398,10 @@ trexio_read_determinant_list (trexio_t* const file, const int64_t offset_file, i
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (offset_file < 0) return TREXIO_INVALID_ARG_2;
|
||||
if (buffer_size_read == NULL) return TREXIO_INVALID_ARG_3;
|
||||
if (*buffer_size_read < 0) return TREXIO_INVALID_ARG_3;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_4;
|
||||
if (trexio_has_determinant_list(file) != TREXIO_SUCCESS) return TREXIO_DSET_MISSING;
|
||||
|
||||
/* Get the number of int bit fields per determinant */
|
||||
@ -5453,13 +5456,21 @@ trexio_read_safe_determinant_list (trexio_t* const file, const int64_t offset_fi
|
||||
}
|
||||
#+end_src
|
||||
|
||||
When writing a determinant list, the indices of the MOs are checked. If they
|
||||
are out of bounds (<0 or >= mo_num), the error ~TREXIO_INVALID_MO_INDEX~ is returned.
|
||||
If the number of orbitals in up-spin or down-spin determinants is different from
|
||||
the number of up-spin and down-spin electrons, the error ~TREXIO_INVALID_ELECTRON_NUM~
|
||||
is returned.
|
||||
|
||||
#+begin_src c :tangle write_determinant_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_determinant_list (trexio_t* const file, const int64_t offset_file, const int64_t buffer_size, const int64_t* dset)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (offset_file < 0) return TREXIO_INVALID_ARG_2;
|
||||
if (buffer_size <= 0) return TREXIO_INVALID_ARG_3;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_4;
|
||||
|
||||
/* Get the number of int bit fields per determinant */
|
||||
int32_t int_num = 0;
|
||||
@ -5471,6 +5482,59 @@ trexio_write_determinant_list (trexio_t* const file, const int64_t offset_file,
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
/* Read the number of mos */
|
||||
int64_t mo_num = 0L;
|
||||
rc = trexio_read_mo_num_64(file, &mo_num);
|
||||
if (rc != TREXIO_SUCCESS) return rc;
|
||||
|
||||
// Read up/dn num
|
||||
int32_t nup = 0;
|
||||
rc = trexio_read_electron_up_num(file, &nup);
|
||||
if (rc != TREXIO_SUCCESS) return rc;
|
||||
|
||||
int32_t ndn = 0;
|
||||
rc = trexio_read_electron_dn_num(file, &ndn);
|
||||
if (rc != TREXIO_SUCCESS) return rc;
|
||||
|
||||
/* Check all determinants */
|
||||
int32_t occ_num_up = 0;
|
||||
int32_t occ_num_dn = 0;
|
||||
|
||||
/* list_up contains first the up-spin orbitals, then the down-spin */
|
||||
int32_t* list_up = (int32_t*) calloc(nup+ndn,sizeof(int32_t));
|
||||
|
||||
if (list_up == NULL) {
|
||||
return TREXIO_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
int32_t* list_dn = &(list_up[nup]);
|
||||
|
||||
for (int64_t i=0 ; i<buffer_size ; i+= 2*int_num) {
|
||||
rc = trexio_to_orbital_list_up_dn(int_num, &dset[i],
|
||||
list_up, list_dn,
|
||||
&occ_num_up, &occ_num_dn);
|
||||
if (rc != TREXIO_SUCCESS) {
|
||||
free(list_up);
|
||||
return rc;
|
||||
}
|
||||
if (occ_num_up != nup || occ_num_dn != ndn) {
|
||||
free(list_up);
|
||||
return TREXIO_INVALID_ELECTRON_NUM;
|
||||
}
|
||||
for (int32_t j=0 ; j<nup+ndn ; ++j) {
|
||||
if (list_up[j] < 0 || list_up[j] >= mo_num) {
|
||||
free(list_up);
|
||||
return TREXIO_INVALID_MO_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
free(list_up);
|
||||
|
||||
/* Up to this point, all the determinants have been checked to
|
||||
have the correct sizes (number of electrons), and MOs in the
|
||||
correct range */
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
@ -5868,18 +5932,18 @@ trexio_exit_code trexio_convert_nao_radius_py (const double r,
|
||||
double* grid_r, int32_t n_grid_r, double* const log_r_out);
|
||||
trexio_exit_code trexio_evaluate_nao_radial (const int32_t shell_index,
|
||||
const double r, const int32_t* const grid_start, const int32_t* const grid_size,
|
||||
const double* const grid_r, const double* const interpolator,
|
||||
const double* const grid_r, const double* const interpolator,
|
||||
const double* const normalization, double* const amplitude);
|
||||
|
||||
trexio_exit_code trexio_evaluate_nao_radial_all (const int32_t shell_num,
|
||||
const int32_t* const nucleus_index, const double* const nucleus_coords,
|
||||
const int32_t* const grid_start, const int32_t* const grid_size,
|
||||
const double* const grid_r, const double* const interpolator, const double* const normalization,
|
||||
const int32_t* const nucleus_index, const double* const nucleus_coords,
|
||||
const int32_t* const grid_start, const int32_t* const grid_size,
|
||||
const double* const grid_r, const double* const interpolator, const double* const normalization,
|
||||
const double rx, const double ry, const double rz, double* const amplitude);
|
||||
|
||||
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
|
||||
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
|
||||
const double r, int64_t* grid_start, int n_grid_st, int64_t* grid_size,
|
||||
int n_grid_si, double* grid_r, int n_grid_r, double* interpolator,
|
||||
int n_grid_si, double* grid_r, int n_grid_r, double* interpolator,
|
||||
int n_interp, double* normalization, int n_norm, double* const amplitude);
|
||||
|
||||
trexio_exit_code trexio_evaluate_nao_radial_all_py (const int32_t shell_num,
|
||||
@ -6079,7 +6143,7 @@ trexio_evaluate_nao_radial (const int32_t shell_index, const double r, const int
|
||||
|
||||
const int32_t i0 = 4*grid_start[shell_index];
|
||||
|
||||
// Convert radius to logarithmic units
|
||||
// Convert radius to logarithmic units
|
||||
double r_log = 0.0;
|
||||
trexio_convert_nao_radius_64 (r, grid_r + grid_start[shell_index], &r_log);
|
||||
int32_t i_log = (int32_t) r_log;
|
||||
@ -6100,7 +6164,7 @@ trexio_evaluate_nao_radial (const int32_t shell_index, const double r, const int
|
||||
|
||||
trexio_exit_code
|
||||
trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nucleus_index, const double* const nucleus_coords, const int32_t* const grid_start,
|
||||
const int32_t* const grid_size, const double* const grid_r, const double* const interpolator,
|
||||
const int32_t* const grid_size, const double* const grid_r, const double* const interpolator,
|
||||
const double* const normalization, const double rx, const double ry, const double rz, double* const amplitude)
|
||||
{
|
||||
if (shell_num < 0) return TREXIO_INVALID_ARG_1;
|
||||
@ -6122,7 +6186,7 @@ trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nu
|
||||
const double r = sqrt(dx*dx + dy*dy + dz*dz);
|
||||
|
||||
// All possibly reported errors have been caught above
|
||||
rc = trexio_evaluate_nao_radial(shell_index, r, grid_start,
|
||||
rc = trexio_evaluate_nao_radial(shell_index, r, grid_start,
|
||||
grid_size, grid_r, interpolator, normalization, &litude[shell_index]);
|
||||
|
||||
if (rc != TREXIO_SUCCESS)
|
||||
@ -6132,9 +6196,9 @@ trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nu
|
||||
return TREXIO_SUCCESS;
|
||||
}
|
||||
|
||||
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
|
||||
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
|
||||
const double r, int64_t* grid_start, int n_grid_st,
|
||||
int64_t* grid_size, int n_grid_si, double* grid_r, int n_grid_r,
|
||||
int64_t* grid_size, int n_grid_si, double* grid_r, int n_grid_r,
|
||||
double* interpolator, int n_interp, double* normalization, int n_norm, double* const amplitude)
|
||||
{
|
||||
// Code needs to be copied because of the use of int64_t mandated by Python
|
||||
@ -6149,7 +6213,7 @@ trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
|
||||
|
||||
const int32_t i0 = 4*grid_start[shell_index];
|
||||
|
||||
// Convert radius to logarithmic units
|
||||
// Convert radius to logarithmic units
|
||||
double r_log = 0.0;
|
||||
trexio_convert_nao_radius_64 (r, grid_r + grid_start[shell_index], &r_log);
|
||||
int32_t i_log = (int32_t) r_log;
|
||||
@ -6197,7 +6261,7 @@ trexio_exit_code trexio_evaluate_nao_radial_all_py (const int32_t shell_num,
|
||||
const double r = sqrt(dx*dx + dy*dy + dz*dz);
|
||||
|
||||
// All possibly reported errors have been caught above
|
||||
rc = trexio_evaluate_nao_radial_py(shell_index, r, grid_start, n_grid_st,
|
||||
rc = trexio_evaluate_nao_radial_py(shell_index, r, grid_start, n_grid_st,
|
||||
grid_size, n_grid_si, grid_r, n_grid_r, interpolator, n_interp, normalization, n_norm, &litudes[shell_index]);
|
||||
if (rc != TREXIO_SUCCESS)
|
||||
return rc;
|
||||
@ -6501,14 +6565,14 @@ def to_orbital_list_up_dn(n_int: int, determinant: list) -> tuple:
|
||||
def convert_nao_radius(r: float, grid_r) -> float:
|
||||
"""Converts the radius r as a distance from a nucleus to the shell
|
||||
s logarithmic grid.
|
||||
|
||||
|
||||
Input:
|
||||
~r~ - the radius to be converted
|
||||
~grid_r~ - The radial grid of the shell. Note that this is only the
|
||||
grid of the shell of interest, not the array of all shells.
|
||||
|
||||
Returns:
|
||||
Float that gives the radius in the shell's logarithmic units
|
||||
Float that gives the radius in the shell's logarithmic units
|
||||
|
||||
Raises:
|
||||
- Exception from AssertionError if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message using trexio_string_of_error.
|
||||
@ -6525,7 +6589,7 @@ def convert_nao_radius(r: float, grid_r) -> float:
|
||||
|
||||
def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpolator, normalization) -> float:
|
||||
"""Evaluates the radial function of a given NAO shell at a distance from its center.
|
||||
|
||||
|
||||
Input:
|
||||
~shell_index~ - index of the shell of interest
|
||||
~r~ - distance from the shell center
|
||||
@ -6538,7 +6602,7 @@ def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpola
|
||||
~normalization~ - array of radial function normalization constants.
|
||||
|
||||
Returns:
|
||||
Value of the spline at the given radius
|
||||
Value of the spline at the given radius
|
||||
|
||||
Raises:
|
||||
- Error from AssertionError if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message using trexio_string_of_error.
|
||||
@ -6555,7 +6619,7 @@ def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpola
|
||||
def evaluate_nao_radial_all(nucleus_index, nucleus_coords, grid_start,
|
||||
grid_size, grid_r, interpolator, normalization, r) -> float:
|
||||
"""Evaluates the radial functions of all NAO shells at a given position in space.
|
||||
|
||||
|
||||
Input:
|
||||
~nucleus_index~ - array giving the centers of the NAO
|
||||
~nucleus_coords~ - array giving the coordinates of the NAO centers
|
||||
@ -6569,7 +6633,7 @@ def evaluate_nao_radial_all(nucleus_index, nucleus_coords, grid_start,
|
||||
~r~ - the position in space at which the functions are evaluated
|
||||
|
||||
Returns:
|
||||
Array of spline values at ~r~
|
||||
Array of spline values at ~r~
|
||||
|
||||
Raises:
|
||||
- Error if ~r~ is not three dimensional
|
||||
@ -6612,11 +6676,9 @@ contains
|
||||
character, intent(in), value :: mode
|
||||
integer(trexio_back_end_t), intent(in), value :: back_end
|
||||
integer(trexio_exit_code), intent(out) :: rc_open
|
||||
character(len=len_trim(filename)+1) :: filename_c
|
||||
integer(trexio_exit_code) :: rc
|
||||
|
||||
filename_c = trim(filename) // c_null_char
|
||||
trexio_open = trexio_open_c(filename_c, mode, back_end, rc_open)
|
||||
trexio_open = trexio_open_c(trim(filename) // c_null_char, mode, back_end, rc_open)
|
||||
if (trexio_open == 0_8 .or. rc_open /= TREXIO_SUCCESS) then
|
||||
return
|
||||
endif
|
||||
@ -6636,10 +6698,8 @@ contains
|
||||
integer(trexio_exit_code) function trexio_inquire (filename)
|
||||
implicit none
|
||||
character(len=*), intent(in) :: filename
|
||||
character(len=len_trim(filename)+1) :: filename_c
|
||||
|
||||
filename_c = trim(filename) // c_null_char
|
||||
trexio_inquire = trexio_inquire_c(filename_c)
|
||||
trexio_inquire = trexio_inquire_c(trim(filename) // c_null_char)
|
||||
end function trexio_inquire
|
||||
#+end_src
|
||||
|
||||
@ -6650,12 +6710,8 @@ contains
|
||||
implicit none
|
||||
character(len=*), intent(in) :: source
|
||||
character(len=*), intent(in) :: destination
|
||||
character(len=len_trim(source)+1) :: source_c
|
||||
character(len=len_trim(destination)+1) :: destination_c
|
||||
|
||||
source_c = trim(source) // c_null_char
|
||||
destination_c = trim(destination) // c_null_char
|
||||
trexio_cp = trexio_cp_c(source_c, destination_c)
|
||||
trexio_cp = trexio_cp_c(trim(source) // c_null_char, trim(destination) // c_null_char)
|
||||
end function trexio_cp
|
||||
#+end_src
|
||||
|
||||
|
@ -1660,12 +1660,12 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
|
||||
if (f == NULL) return TREXIO_FILE_ERROR;
|
||||
|
||||
/* Specify the line length in order to offset properly.
|
||||
Each 64-bit integer takes at most 10 slots and requires one space,
|
||||
Each 64-bit integer takes at most 20 slots and requires one space,
|
||||
we have int_num integers per up-spin determinant,
|
||||
then this number is doubled because we have the same number for down-spin electrons,
|
||||
and then one newline char.
|
||||
,*/
|
||||
uint64_t line_length = dims[1]*11UL + 1UL; // 10 digits per int64_t bitfield + 1 space = 11 spots + 1 newline char
|
||||
uint64_t line_length = dims[1]*21UL + 1UL; // 20 digits per int64_t bitfield + 1 space = 11 spots + 1 newline char
|
||||
|
||||
/* Offset in the file according to the provided value of offset_file and optimal line_length */
|
||||
fseek(f, (long) offset_file * line_length, SEEK_SET);
|
||||
@ -1677,7 +1677,7 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
|
||||
uint32_t buf_size = sizeof(buffer);
|
||||
/* Parameters to post-process the buffer and to get bit fields integers */
|
||||
uint64_t accum = 0UL;
|
||||
uint32_t shift_int64 = 11U;
|
||||
uint32_t shift_int64 = 21U;
|
||||
/* Counter for number of elements beind processed */
|
||||
uint64_t count = 0UL;
|
||||
for (uint64_t i=0UL; i < dims[0]; ++i) {
|
||||
@ -1697,7 +1697,7 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
|
||||
Thus, we parse the buffer string int_num*2 times to get the bit field determinants.
|
||||
,*/
|
||||
for (uint32_t j=0; j < (uint32_t) dims[1]; ++j) {
|
||||
rc = sscanf(buffer+accum, "%10" SCNd64, list + dims[1]*i + j);
|
||||
rc = sscanf(buffer+accum, "%20" SCNd64, list + dims[1]*i + j);
|
||||
if (rc <= 0) {
|
||||
fclose(f);
|
||||
return TREXIO_FAILURE;
|
||||
@ -1747,7 +1747,7 @@ trexio_exit_code trexio_text_write_determinant_list(trexio_t* const file,
|
||||
|
||||
/* The loop below is needed to write a line with int bit fields for alpha and beta electrons */
|
||||
for (uint32_t j=0; j < (uint32_t) dims[1]; ++j) {
|
||||
rc = fprintf(f, "%10" PRId64 " ", *(list + i*dims[1] + j));
|
||||
rc = fprintf(f, "%20" PRId64 " ", *(list + i*dims[1] + j));
|
||||
if (rc <= 0) {
|
||||
fclose(f);
|
||||
return TREXIO_FAILURE;
|
||||
|
@ -32,6 +32,16 @@ static int test_write_determinant (const char* file_name, const back_end_t backe
|
||||
assert(rc == TREXIO_SUCCESS);
|
||||
}
|
||||
|
||||
// write number of up and down electrons for checking consistency of determinants
|
||||
if (trexio_has_electron_up_num(file) == TREXIO_HAS_NOT) {
|
||||
rc = trexio_write_electron_up_num(file, 4);
|
||||
assert(rc == TREXIO_SUCCESS);
|
||||
}
|
||||
if (trexio_has_electron_dn_num(file) == TREXIO_HAS_NOT) {
|
||||
rc = trexio_write_electron_dn_num(file, 3);
|
||||
assert(rc == TREXIO_SUCCESS);
|
||||
}
|
||||
|
||||
// get the number of int64 bit fields per determinant
|
||||
int int_num;
|
||||
rc = trexio_get_int64_num(file, &int_num);
|
||||
@ -96,7 +106,6 @@ static int test_write_determinant (const char* file_name, const back_end_t backe
|
||||
// free the allocated memeory
|
||||
free(det_list);
|
||||
free(det_coef);
|
||||
printf("write determinants OK\n");
|
||||
|
||||
/*================= END OF TEST ==================*/
|
||||
|
||||
@ -133,7 +142,6 @@ static int test_has_determinant(const char* file_name, const back_end_t backend)
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
/*================= END OF TEST ==================*/
|
||||
printf("has_determinant OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -218,7 +226,7 @@ static int test_read_determinant (const char* file_name, const back_end_t backen
|
||||
/*
|
||||
printf("%s\n", trexio_string_of_error(rc));
|
||||
for (int i=0; i<size_r; i++) {
|
||||
printf("%lld %lld\n", det_list_read[6*i], det_list_read[6*i+5]);
|
||||
printf("%ld %ld\n", det_list_read[6*i], det_list_read[6*i+5]);
|
||||
}
|
||||
*/
|
||||
assert(rc == TREXIO_END);
|
||||
@ -305,7 +313,6 @@ int main(){
|
||||
assert (rc == 0);
|
||||
|
||||
// check the first write attempt (SIZE elements written in N_CHUNKS chunks)
|
||||
printf("mo_num = %d\n", mo_nums[i]);
|
||||
test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0L, mo_nums[i]);
|
||||
test_has_determinant (TREXIO_FILE, TEST_BACKEND);
|
||||
test_read_determinant (TREXIO_FILE, TEST_BACKEND, 0L);
|
||||
|
130
tests/test_f.f90
130
tests/test_f.f90
@ -5,6 +5,7 @@ program test_trexio
|
||||
|
||||
integer :: rc
|
||||
logical :: have_hdf5
|
||||
character*(64) :: trexio_file1, trexio_file2
|
||||
|
||||
print'(a)' , "============================================"
|
||||
print'(a,a)' , " TREXIO VERSION STRING : ", TREXIO_PACKAGE_VERSION
|
||||
@ -14,20 +15,40 @@ program test_trexio
|
||||
|
||||
rc = trexio_info()
|
||||
|
||||
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock ' &
|
||||
// 'test_write_f2.dir/*.txt test_write_f2.dir/*.txt.size test_write_f2.dir/.lock && ' &
|
||||
// 'rm -fd -- test_write_f.dir test_write_f2.dir')
|
||||
print *, 'call test_write(''test_write_f.dir'', TREXIO_TEXT)'
|
||||
call test_write('test_write_f.dir', TREXIO_TEXT)
|
||||
rc = trexio_cp('test_write_f.dir', 'test_write_f2.dir')
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
print *, 'call test_read(''test_write_f2.dir'', TREXIO_TEXT)'
|
||||
call test_read('test_write_f2.dir', TREXIO_TEXT)
|
||||
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock ' &
|
||||
// 'test_write_f2.dir/*.txt test_write_f2.dir/*.txt.size test_write_f2.dir/.lock && ' &
|
||||
// 'rm -fd -- test_write_f.dir test_write_f2.dir')
|
||||
trexio_file1 = 'test_write_f.dir'
|
||||
trexio_file2 = 'test_write_f2.dir'
|
||||
|
||||
call test_read_void('test_write_f.dir', TREXIO_TEXT)
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/*.txt')
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/*.txt.size')
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/.lock ')
|
||||
call system('rm -rf -- '//trim(trexio_file1))
|
||||
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/*.txt')
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/*.txt.size')
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/.lock ')
|
||||
call system('rm -rf -- '//trim(trexio_file2))
|
||||
|
||||
print *, 'call test_write'
|
||||
call test_write('test_write_f.dir', TREXIO_TEXT)
|
||||
|
||||
rc = trexio_cp(trexio_file1, trexio_file2)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
|
||||
print *, 'call test_read'
|
||||
call test_read(trexio_file2, TREXIO_TEXT)
|
||||
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/*.txt')
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/*.txt.size')
|
||||
call system('rm -f -- '//trim(trexio_file1)//'/.lock ')
|
||||
call system('rm -rf -- '//trim(trexio_file1))
|
||||
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/*.txt')
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/*.txt.size')
|
||||
call system('rm -f -- '//trim(trexio_file2)//'/.lock ')
|
||||
call system('rm -rf -- '//trim(trexio_file2))
|
||||
|
||||
print *, 'call test_read_void'
|
||||
call test_read_void(trexio_file1, TREXIO_TEXT)
|
||||
|
||||
! No way to conditionally check whether compilation was done with HDF5
|
||||
! So temporarily disable the test for HDF5 back end at the moment
|
||||
@ -69,16 +90,18 @@ subroutine test_write(file_name, back_end)
|
||||
double precision :: charge(12)
|
||||
double precision :: coord(3,12)
|
||||
|
||||
character(len=32), allocatable :: sym_str
|
||||
character(len=32) :: sym_str
|
||||
character(len=8), allocatable :: label(:)
|
||||
double precision, allocatable :: energy(:)
|
||||
integer , allocatable :: spin(:)
|
||||
|
||||
! sparse data
|
||||
integer(4) :: index_sparse_ao_2e_int_eri(4,100)
|
||||
double precision :: value_sparse_ao_2e_int_eri(100)
|
||||
integer(4), allocatable :: index_sparse_ao_2e_int_eri(:,:)
|
||||
double precision, allocatable :: value_sparse_ao_2e_int_eri(:)
|
||||
|
||||
! determinants
|
||||
integer :: nup, ndn
|
||||
integer :: det_occ(10,2)
|
||||
integer*8 :: det_list(6, 50)
|
||||
integer*8 :: det_num
|
||||
integer :: int_num
|
||||
@ -87,9 +110,12 @@ subroutine test_write(file_name, back_end)
|
||||
integer(8) :: buf_size_sparse, buf_size_det, offset
|
||||
integer :: state_id
|
||||
|
||||
|
||||
|
||||
buf_size_sparse = 100/n_buffers
|
||||
buf_size_det = 50/n_buffers
|
||||
|
||||
allocate(index_sparse_ao_2e_int_eri(4,100), value_sparse_ao_2e_int_eri(100))
|
||||
! fill sparse indices and values
|
||||
do i = 1, 100
|
||||
index_sparse_ao_2e_int_eri(1,i) = 4*i - 3
|
||||
@ -100,10 +126,16 @@ subroutine test_write(file_name, back_end)
|
||||
enddo
|
||||
|
||||
! fill determinant list
|
||||
nup = 8
|
||||
ndn = 6
|
||||
det_occ = 0
|
||||
det_occ(1:nup,1) = (/ 1, 2, 3, 4, 76, 128, 129, 143 /)
|
||||
det_occ(1:ndn,2) = (/ 1, 3, 4, 80, 81, 139 /)
|
||||
do i = 1, 50
|
||||
do j = 1, 6
|
||||
det_list(j,i) = 6*i+(j-1) - 5
|
||||
enddo
|
||||
rc = trexio_to_bitfield_list(det_occ(1:8,1), nup, det_list(1:3,i), 3)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
rc = trexio_to_bitfield_list(det_occ(1:6,2), ndn, det_list(4:6,i), 3)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
enddo
|
||||
|
||||
! parameters to be written
|
||||
@ -161,6 +193,18 @@ subroutine test_write(file_name, back_end)
|
||||
rc = trexio_has_nucleus_charge(trex_file)
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
|
||||
|
||||
rc = trexio_has_electron_up_num(trex_file)
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2.1')
|
||||
|
||||
rc = trexio_write_electron_up_num(trex_file, nup)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
|
||||
rc = trexio_has_electron_dn_num(trex_file)
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2.2')
|
||||
|
||||
rc = trexio_write_electron_dn_num(trex_file, ndn)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
|
||||
rc = trexio_has_ao_2e_int_eri(trex_file)
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 3')
|
||||
|
||||
@ -187,7 +231,6 @@ subroutine test_write(file_name, back_end)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE LABEL')
|
||||
|
||||
rc = trexio_write_nucleus_point_group(trex_file, sym_str, 32)
|
||||
deallocate(sym_str)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE POINT GROUP')
|
||||
|
||||
rc = trexio_write_basis_shell_num(trex_file, basis_shell_num)
|
||||
@ -244,6 +287,7 @@ subroutine test_write(file_name, back_end)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE DET LIST')
|
||||
offset = offset + buf_size_det
|
||||
enddo
|
||||
deallocate(index_sparse_ao_2e_int_eri, value_sparse_ao_2e_int_eri)
|
||||
|
||||
rc = trexio_has_nucleus_num(trex_file)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 1')
|
||||
@ -313,7 +357,7 @@ subroutine test_read(file_name, back_end)
|
||||
|
||||
! determinant data
|
||||
integer*8 :: det_list(6,50)
|
||||
integer*8 :: det_list_check(3)
|
||||
integer*8 :: det_list_check(6)
|
||||
integer*8 :: read_buf_det_size = 20
|
||||
integer*8 :: offset_det_read = 10
|
||||
integer*8 :: offset_det_data_read = 5
|
||||
@ -477,17 +521,39 @@ subroutine test_read(file_name, back_end)
|
||||
! read a chunk of determinants
|
||||
rc = trexio_read_determinant_list(trex_file, offset_det_read, read_buf_det_size, &
|
||||
det_list(1, offset_det_data_read + 1))
|
||||
!do i = 1,50
|
||||
! write(*,*) det_list(1,i)
|
||||
!enddo
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (det_list(1, 1) == 0 .and. &
|
||||
det_list(1, offset_det_data_read + 1) == offset_det_read*6 + 1) then
|
||||
write(*,*) 'SUCCESS READ DET LIST'
|
||||
else
|
||||
print *, 'FAILURE DET LIST CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
det_list_check = (/15_8, -9223372036854773760_8, 16385_8, 13_8, 98304_8, 1024_8 /)
|
||||
do i = 1,offset_det_data_read
|
||||
do j=1,6
|
||||
if (det_list(j,i) /= 0_8) then
|
||||
print *, det_list(j,i)
|
||||
print *, 'FAILURE DET LIST CHECK 1'
|
||||
call exit(-1)
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do i = offset_det_data_read+1, offset_det_data_read+read_buf_det_size
|
||||
do j=1,6
|
||||
if (det_list(j,i) /= det_list_check(j)) then
|
||||
print *, det_list(j,i)
|
||||
print *, 'FAILURE DET LIST CHECK 2'
|
||||
call exit(-1)
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do i = offset_det_data_read+read_buf_det_size+1,50
|
||||
do j=1,6
|
||||
if (det_list(j,i) /= 0_8) then
|
||||
print *, det_list(j,i)
|
||||
print *, 'FAILURE DET LIST CHECK 3'
|
||||
call exit(-1)
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
|
||||
write(*,*) 'SUCCESS READ DET LIST'
|
||||
|
||||
! read the total number of stored determinants
|
||||
rc = trexio_read_determinant_num_64(trex_file, determinant_num)
|
||||
@ -509,7 +575,7 @@ subroutine test_read(file_name, back_end)
|
||||
! Print binary representation of the first integer bit field of a given determinant
|
||||
!write(*,'(B64.64)') det_list(1, offset_det_data_read+1)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (occ_num_up == 16 .and. occ_num_dn == 5) then
|
||||
if (occ_num_up == 8 .and. occ_num_dn == 6) then
|
||||
write(*,*) 'SUCCESS CONVERT DET LIST'
|
||||
else
|
||||
print *, 'FAILURE DET CONVERT CHECK'
|
||||
|
Loading…
x
Reference in New Issue
Block a user