1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-07-22 18:57:39 +02:00

Merge branch 'master' into index

This commit is contained in:
Anthony Scemama 2021-06-10 00:32:20 +02:00
commit 1b504d92bf
9 changed files with 305 additions and 78 deletions

63
.github/workflows/actions.yml vendored Normal file
View File

@ -0,0 +1,63 @@
name: TREXIO CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
trexio_ubuntu:
runs-on: ubuntu-latest
name: x86 Ubuntu latest
steps:
- uses: actions/checkout@v2
- name: install dependencies
run: |
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt-get install libhdf5-dev emacs26
- name: configure with autotools
run: |
./autogen.sh
TREXIO_DEVEL=1 ./configure --enable-silent-rules
- name: compile TREXIO
run: make -j 2
- name: check TREXIO
run: make check
- name: clean
run: make clean
trexio_macos:
runs-on: macos-latest
name: x86 MacOS latest
steps:
- uses: actions/checkout@v2
- name: install dependencies
run: |
brew install emacs
brew install hdf5
brew install automake
- name: configure with autotools
run: |
./autogen.sh
TREXIO_DEVEL=1 ./configure FC=gfortran-10 --enable-silent-rules
- name: compile TREXIO
run: make -j 2
- name: check TREXIO
run: make check
- name: clean
run: make clean

View File

@ -87,7 +87,7 @@ tests_test_f_SOURCES = $(test_trexio_f) tests/test_f.f90
tests_test_f_LDADD = src/libtrexio.la
tests_test_f_LDFLAGS = -no-install
$(test_trexio_f):
$(test_trexio_f): $(trexio_f)
cp $(trexio_f) $(test_trexio_f)
clean-local:

View File

@ -25,11 +25,12 @@ module trexio
implicit none
integer, parameter :: trexio_exit_code = 4
integer, parameter :: trexio_backend = 4
integer, parameter :: TREXIO_HDF5 = 0
integer, parameter :: TREXIO_TEXT = 1
! integer, parameter :: TREXIO_JSON = 2
integer, parameter :: TREXIO_INVALID_BACK_END = 2
integer(trexio_backend), parameter :: TREXIO_HDF5 = 0
integer(trexio_backend), parameter :: TREXIO_TEXT = 1
! integer(trexio_backend), parameter :: TREXIO_JSON = 2
integer(trexio_backend), parameter :: TREXIO_INVALID_BACK_END = 2
#+end_src
#+end_src
@ -586,9 +587,10 @@ trexio_open(const char* file_name, const char mode,
interface
integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open")
use, intrinsic :: iso_c_binding
character(kind=c_char), dimension(*) :: filename
character, intent(in), value :: mode
integer, intent(in), value :: backend
import
character(kind=c_char), dimension(*) :: filename
character, intent(in), value :: mode
integer(trexio_backend), intent(in), value :: backend
end function trexio_open_c
end interface
#+end_src
@ -1560,10 +1562,9 @@ contains
integer(8) function trexio_open (filename, mode, backend)
use, intrinsic :: iso_c_binding
implicit none
character(len=*) :: filename
character, intent(in), value :: mode
integer, intent(in), value :: backend
character(len=*) :: filename
character, intent(in), value :: mode
integer(trexio_backend), intent(in), value :: backend
character(len=len_trim(filename)+1) :: filename_c
integer :: rc

View File

@ -332,7 +332,7 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
/* High-level H5LT API. No need to deal with dataspaces and datatypes */
status = H5LTread_dataset(f->$group$_group,
$GROUP_DSET$_NAME,
H5T_NATIVE_$GROUP_DSET_H5_DTYPE$,
H5T_$GROUP_DSET_H5_DTYPE$,
$group_dset$);
if (status < 0) return TREXIO_FAILURE;
@ -362,7 +362,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
const herr_t status = H5LTmake_dataset(f->$group$_group,
$GROUP_DSET$_NAME,
(int) rank, (const hsize_t*) dims,
H5T_NATIVE_$GROUP_DSET_H5_DTYPE$,
H5T_$GROUP_DSET_H5_DTYPE$,
$group_dset$);
if (status < 0) return TREXIO_FAILURE;
@ -372,7 +372,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
if (dset_id <= 0) return TREXIO_INVALID_ID;
const herr_t status = H5Dwrite(dset_id,
H5T_NATIVE_$GROUP_DSET_H5_DTYPE$,
H5T_$GROUP_DSET_H5_DTYPE$,
H5S_ALL, H5S_ALL, H5P_DEFAULT,
$group_dset$);

View File

@ -15,11 +15,15 @@ int main() {
assert (rc == 0);
test_write("test_write.h5", TREXIO_HDF5);
test_read ("test_write.h5", TREXIO_HDF5);
rc = system("rm -rf test_write.h5");
assert (rc == 0);
rc = system("rm -rf test_write.dir");
assert (rc == 0);
test_write("test_write.dir", TREXIO_TEXT);
test_read ("test_write.dir", TREXIO_TEXT);
rc = system("rm -rf test_write.dir");
assert (rc == 0);
return 0;
}

View File

@ -1,21 +1,39 @@
program test_trexio
use trexio
implicit none
call test_write()
call test_read()
call system('rm -rf trexio_test_fort')
print *, 'call test_write(''trexio_test_fort'', TREXIO_TEXT)'
call test_write('trexio_test_fort', TREXIO_TEXT)
print *, 'call test_read(''trexio_test_fort'', TREXIO_TEXT)'
call test_read('trexio_test_fort', TREXIO_TEXT)
call system('rm -rf trexio_test_fort')
call system('rm -rf trexio_test_fort')
print *, 'call test_write(''trexio_test_fort.h5'', TREXIO_HDF5)'
call test_write('trexio_test_fort.h5', TREXIO_HDF5)
print *, 'call test_read(''trexio_test_fort.h5'', TREXIO_HDF5)'
call test_read('trexio_test_fort.h5', TREXIO_HDF5)
call system('rm -rf trexio_test_fort.h5')
end program test_trexio
subroutine test_write()
subroutine test_write(file_name, back_end)
! ============ Test write functionality =============== !
use trexio
implicit none
character*(*), intent(in) :: file_name
integer(trexio_backend), intent(in) :: back_end
integer(8) :: trex_file
integer :: rc = 1
integer :: num
character*(128) :: str
double precision :: charge(12)
double precision :: coord(3,12)
@ -39,33 +57,84 @@ subroutine test_write()
! ================= START OF TEST ===================== !
trex_file = trexio_open('trexio_test_fort', 'w', TREXIO_TEXT)
! trex_file = trexio_open('test_hdf5_fort.h5', 'w', TREXIO_HDF5)
trex_file = trexio_open(file_name, 'w', back_end)
rc = trexio_has_nucleus_num(trex_file)
if (rc == TREXIO_HAS_NOT) write(*,*) 'SUCCESS HAS NOT 1'
if (rc == TREXIO_HAS_NOT) then
write(*,*) 'SUCCESS HAS NOT 1'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_has_nucleus_charge(trex_file)
if (rc == TREXIO_HAS_NOT) write(*,*) 'SUCCESS HAS NOT 2'
if (rc == TREXIO_HAS_NOT) then
write(*,*) 'SUCCESS HAS NOT 2'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_write_nucleus_num(trex_file, num)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS WRITE NUM'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS WRITE NUM'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_write_nucleus_charge(trex_file, charge)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS WRITE CHARGE'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS WRITE CHARGE'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_write_nucleus_coord(trex_file, coord)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS WRITE COORD'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS WRITE COORD'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_has_nucleus_num(trex_file)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS HAS 1'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS HAS 1'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_has_nucleus_coord(trex_file)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS HAS 2'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS HAS 2'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_close(trex_file)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS CLOSE'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS CLOSE'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
! ---------------------------------- !
! to modify fiels of existing file:
! to modify fields of existing file:
! text backend -> open with 'w'
! hdf5 backend -> open with 'a'
! ---------------------------------- !
@ -85,13 +154,19 @@ subroutine test_write()
end subroutine test_write
subroutine test_read()
subroutine test_read(file_name, back_end)
! ============ Test read functionality =============== !
use trexio
implicit none
character*(*), intent(in) :: file_name
integer(trexio_backend), intent(in) :: back_end
integer(8) :: trex_file
integer :: rc = 1
@ -106,26 +181,48 @@ subroutine test_read()
! ================= START OF TEST ===================== !
trex_file = trexio_open('trexio_test_fort', 'r', TREXIO_TEXT)
! trex_file = trexio_open('test_hdf5_fort.h5', 'r', TREXIO_HDF5)
trex_file = trexio_open(file_name, 'r', back_end)
rc = trexio_read_nucleus_num(trex_file, num_read)
if (rc == TREXIO_SUCCESS .and. num_read == num) write(*,*) 'SUCCESS READ NUM'
if (rc == TREXIO_SUCCESS .and. num_read == num) then
write(*,*) 'SUCCESS READ NUM'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
rc = trexio_read_nucleus_charge(trex_file, charge)
if (rc == TREXIO_SUCCESS .and. (abs(charge(11) - 1.0) < 1.0D-8) ) write(*,*) 'SUCCESS READ CHARGE'
if (rc == TREXIO_SUCCESS .and. (dabs(charge(11) - 1.d0) < 1.0D-8) ) then
write(*,*) 'SUCCESS READ CHARGE'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(-1)
endif
rc = trexio_read_nucleus_coord(trex_file, coord)
if (rc == TREXIO_SUCCESS .and. (abs(coord(2,1) - 1.39250319d0) < 1.0D-8) ) write(*,*) 'SUCCESS READ COORD'
if (rc == TREXIO_SUCCESS .and. (dabs(coord(2,1) - 1.39250319d0) < 1.0D-8) ) then
write(*,*) 'SUCCESS READ COORD'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(-1)
endif
rc = trexio_close(trex_file)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS CLOSE'
if (rc == TREXIO_SUCCESS) then
write(*,*) 'SUCCESS CLOSE'
else
call trexio_string_of_error(TREXIO_READONLY,str)
print *, trim(str)
call exit(1)
endif
call trexio_string_of_error(TREXIO_READONLY,str)
write(*,*) str
! ================= END OF TEST ===================== !

View File

@ -462,7 +462,7 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
# specify details required to replace templated variables later
if v[0] == 'float':
datatype = 'double'
group_dset_h5_dtype = 'double'
group_dset_h5_dtype = 'native_double'
group_dset_f_dtype_default= 'real(8)'
group_dset_f_dtype_double = 'real(8)'
group_dset_f_dtype_single = 'real(4)'
@ -474,7 +474,7 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
group_dset_std_dtype_in = 'lf'
elif v[0] == 'int':
datatype = 'int64_t'
group_dset_h5_dtype = 'int64'
group_dset_h5_dtype = 'native_int64'
group_dset_f_dtype_default= 'integer(4)'
group_dset_f_dtype_double = 'integer(8)'
group_dset_f_dtype_single = 'integer(4)'

View File

@ -37,17 +37,18 @@
} ,
"basis": {
"type" : [ "str" , [] ]
, "shell_num" : [ "int" , [] ]
, "shell_center" : [ "index", [ "basis.shell_num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.shell_num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.shell_num" ] ]
, "shell_factor" : [ "float", [ "basis.shell_num" ] ]
, "prim_index" : [ "index", [ "basis.shell_num" ] ]
, "prim_num" : [ "int" , [] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
"type" : [ "str" , [] ]
, "num" : [ "int" , [] ]
, "prim_num" : [ "int" , [] ]
, "nucleus_index" : [ "index" , [ "nucleus.num" ] ]
, "nucleus_shell_num" : [ "int" , [ "nucleus.num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.num" ] ]
, "shell_factor" : [ "float", [ "basis.num" ] ]
, "shell_prim_index" : [ "index" , [ "basis.num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
} ,
"ao": {

115
trex.org
View File

@ -162,8 +162,8 @@ arrays are 0-base. Hence, we introduce the ~index~ type which is an
* Basis set
We consider here basis functions centered on nuclei. Hence, we enable
the possibility to define \emph{dummy atoms} to place basis functions
in random positions.
the possibility to define /dummy atoms/ to place basis functions in
random positions.
The atomic basis set is defined as a list of shells. Each shell $s$ is
centered on a center $A$, possesses a given angular momentum $l$ and a
@ -189,25 +189,28 @@ arrays are 0-base. Hence, we introduce the ~index~ type which is an
Some codes assume that the contraction coefficients are for a linear
combination of /normalized/ primitives. This implies that a normalization
constant for the primitive $ks$ needs to be computed and stored. If
this normalization factor is not required, set $f_{ks}$ to one.
this normalization factor is not required, $f_{ks}=1$.
Some codes assume that the basis function are normalized. This
implies the computation of an extra normalization factor, $\mathcal{N}_s$.
If the the basis function is not normalized, set $\mathcal{N}_s=1$.
If the the basis function is not considered normalized, $\mathcal{N}_s=1$.
All the basis set parameters are stored in one-dimensional arrays:
#+NAME: basis
| ~type~ | ~str~ | | Type of basis set: "Gaussian" or "Slater" |
| ~shell_num~ | ~int~ | | Total Number of shells |
| ~shell_center~ | ~index~ | ~(basis.shell_num)~ | Nucleus on which the shell is centered ($A$) |
| ~shell_ang_mom~ | ~int~ | ~(basis.shell_num)~ | Angular momentum ~0:S, 1:P, 2:D, ...~ |
| ~shell_prim_num~ | ~int~ | ~(basis.shell_num)~ | Number of primitives in the shell ($N_{\text{prim}}$) |
| ~shell_factor~ | ~float~ | ~(basis.shell_num)~ | Normalization factor of the shell ($\mathcal{N}_s$) |
| ~prim_index~ | ~index~ | ~(basis.shell_num)~ | Index of the first primitive in the complete list |
| ~prim_num~ | ~int~ | | Total number of primitives |
| ~exponent~ | ~float~ | ~(basis.prim_num)~ | Exponents of the primitives ($\gamma_{ks}) |
| ~coefficient~ | ~float~ | ~(basis.prim_num)~ | Coefficients of the primitives ($a_{ks}$) |
| ~prim_factor~ | ~float~ | ~(basis.prim_num)~ | Normalization coefficients for the primitives ($f_{ks}$) |
| ~type~ | ~str~ | | Type of basis set: "Gaussian" or "Slater" |
| ~num~ | ~int~ | | Total Number of shells |
| ~prim_num~ | ~int~ | | Total number of primitives |
| ~nucleus_index~ | ~index~ | ~(nucleus.num)~ | Index of the first shell of each nucleus ($A$) |
| ~nucleus_shell_num~ | ~int~ | ~(nucleus.num)~ | Number of shells for each nucleus |
| ~shell_ang_mom~ | ~int~ | ~(basis.num)~ | Angular momentum ~0:S, 1:P, 2:D, ...~ |
| ~shell_prim_num~ | ~int~ | ~(basis.num)~ | Number of primitives in the shell ($N_{\text{prim}}$) |
| ~shell_factor~ | ~float~ | ~(basis.num)~ | Normalization factor of the shell ($\mathcal{N}_s$) |
| ~shell_prim_index~ | ~index~ | ~(basis.num)~ | Index of the first primitive in the complete list |
| ~exponent~ | ~float~ | ~(basis.prim_num)~ | Exponents of the primitives ($\gamma_{ks}) |
| ~coefficient~ | ~float~ | ~(basis.prim_num)~ | Coefficients of the primitives ($a_{ks}$) |
| ~prim_factor~ | ~float~ | ~(basis.prim_num)~ | Normalization coefficients for the primitives ($f_{ks}$) |
#+CALL: json(data=basis, title="basis")
@ -215,21 +218,78 @@ arrays are 0-base. Hence, we introduce the ~index~ type which is an
:results:
#+begin_src python :tangle trex.json
"basis": {
"type" : [ "str" , [] ]
, "shell_num" : [ "int" , [] ]
, "shell_center" : [ "index", [ "basis.shell_num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.shell_num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.shell_num" ] ]
, "shell_factor" : [ "float", [ "basis.shell_num" ] ]
, "prim_index" : [ "index", [ "basis.shell_num" ] ]
, "prim_num" : [ "int" , [] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
"type" : [ "str" , [] ]
, "num" : [ "int" , [] ]
, "prim_num" : [ "int" , [] ]
, "nucleus_index" : [ "index" , [ "nucleus.num" ] ]
, "nucleus_shell_num" : [ "int" , [ "nucleus.num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.num" ] ]
, "shell_factor" : [ "float", [ "basis.num" ] ]
, "shell_prim_index" : [ "index" , [ "basis.num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
} ,
#+end_src
:end:
For example, consider H_2 with the following basis set (in GAMESS
format), where both the AOs and primitives are considered normalized:
#+BEGIN_EXAMPLE
HYDROGEN
S 5
1 3.387000E+01 6.068000E-03
2 5.095000E+00 4.530800E-02
3 1.159000E+00 2.028220E-01
4 3.258000E-01 5.039030E-01
5 1.027000E-01 3.834210E-01
S 1
1 3.258000E-01 1.000000E+00
S 1
1 1.027000E-01 1.000000E+00
P 1
1 1.407000E+00 1.000000E+00
P 1
1 3.880000E-01 1.000000E+00
D 1
1 1.057000E+00 1.0000000
#+END_EXAMPLE
we have:
#+BEGIN_EXAMPLE
type = "Gaussian"
num = 12
prim_num = 20
nucleus_index = [0 , 6]
shell_ang_mom = [0 , 0 , 0 , 1 , 1 , 2 , 0 , 0 , 0 , 1 , 1 , 2 ]
shell_prim_num = [5 , 1 , 1 , 1 , 1 , 1 , 5 , 1 , 1 , 1 , 1 , 1 ]
shell_prim_index = [0 , 5 , 6 , 7 , 8 , 9 , 10, 15, 16, 17, 18, 19]
shell_factor = [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]
exponent =
[ 33.87, 5.095, 1.159, 0.3258, 0.1027, 0.3258, 0.1027, 1.407,
0.388, 1.057, 33.87, 5.095, 1.159, 0.3258, 0.1027, 0.3258, 0.1027, 1.407,
0.388, 1.057]
coefficient =
[ 0.006068, 0.045308, 0.202822, 0.503903, 0.383421, 1.0, 1.0,
1.0, 1.0, 1.0, 0.006068, 0.045308, 0.202822, 0.503903, 0.383421, 1.0, 1.0,
1.0, 1.0, 1.0]
prim_factor =
[ 1.0006253235944540e+01, 2.4169531573445120e+00, 7.9610924849766440e-01
3.0734305383061117e-01, 1.2929684417481876e-01, 3.0734305383061117e-01,
1.2929684417481876e-01, 2.1842769845268308e+00, 4.3649547399719840e-01,
1.8135965626177861e+00, 1.0006253235944540e+01, 2.4169531573445120e+00,
7.9610924849766440e-01, 3.0734305383061117e-01, 1.2929684417481876e-01,
3.0734305383061117e-01, 1.2929684417481876e-01, 2.1842769845268308e+00,
4.3649547399719840e-01, 1.8135965626177861e+00 ]
#+END_EXAMPLE
* Atomic orbitals
Going from the atomic basis set to AOs implies a systematic
@ -254,7 +314,8 @@ arrays are 0-base. Hence, we introduce the ~index~ type which is an
\chi_i (\mathbf{r}) = \mathcal{N}_i\, P_{\eta(i)}(\mathbf{r})\, R_{\theta(i)} (\mathbf{r})
\]
where $i$ is the atomic orbital index, $P$ encodes for either the
where $i$ is the atomic orbital index,
$P$ encodes for either the
polynomials or the spherical harmonics, $\theta(i)$ returns the
shell on which the AO is expanded, and $\eta(i)$ denotes which
angular function is chosen.