diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 4897de0..40fa30e 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -112,8 +112,8 @@ jobs: run: make maintainer-clean trexio_macos: - name: x86 MacOS 11 - runs-on: macos-11 + name: x86 MacOS 12 + runs-on: macos-12 steps: - uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 @@ -123,17 +123,27 @@ jobs: brew install emacs brew install hdf5 brew install automake + brew --prefix hdf5 - name: configure with autotools run: | ./autogen.sh - ./configure FC=gfortran-10 --enable-silent-rules + ./configure FC=gfortran-12 --enable-silent-rules - name: compile TREXIO run: make -j3 - name: check TREXIO run: make -j3 check + + - name: compile Python API + run: | + export H5_CFLAGS="-I$(brew --prefix hdf5)/include" + export H5_LDFLAGS="-L$(brew --prefix hdf5)/lib" + make python-install + + - name: test Python API + run: make python-test - name: Archive test log file if: failure() diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 5dbdf19..adddb7c 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -21,7 +21,7 @@ jobs: message: ${{ steps.commit_message.outputs.message }} steps: - name: Checkout the repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Gets the correct commit message for pull request with: ref: ${{ github.event.pull_request.head.sha }} @@ -42,14 +42,14 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - manylinux_tag: [2010_x86_64, 2014_x86_64, 2_24_x86_64] + manylinux_tag: [2014_x86_64, 2_24_x86_64] steps: - name: Checkout the branch - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: '3.9' @@ -103,22 +103,14 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-10.15] - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] -# TODO: normally, one could include macos-11 and the OS list above but the produced wheels receive an error upon installation: -# ERROR: trexio-1.1.0-cp39-cp39-macosx_11_0_x86_64.whl is not a supported wheel on this platform. -# This happens even with the MACOSX_DEPLOYMENT_TARGET trick. Perhaps it can be solved by configuring the build system -# to produce the wheels for MacOS-11 from the very beginning - #exclude: - # - os: macos-11 - env: - H5_LDFLAGS: '-L/usr/local/Cellar/hdf5/1.12.1/lib' - H5_CFLAGS: '-I/usr/local/Cellar/hdf5/1.12.1/include' + os: [macos-12] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -128,11 +120,6 @@ jobs: - name: Install HDF5 run: brew install hdf5@1.12 - # This step is needed to produce wheels with the correct platform tag for MacOS-11 (Big Sur) - #- name: Set MACOSX_DEPLOYMENT_TARGET environment variable - # if: ${{ matrix.os == 'macos-11' }} - # run: echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> $GITHUB_ENV - - name: Compute the PYTREXIO_VERSION environment variable run: echo "PYTREXIO_VERSION=$(grep __version__ python/pytrexio/_version.py | cut -d\ -f3 | tr -d '"')" >> $GITHUB_ENV @@ -158,6 +145,8 @@ jobs: run: | mkdir wheelhouse/ cd trexio-${{ env.PYTREXIO_VERSION }}/ + export H5_CFLAGS="-I$(brew --prefix hdf5)/include" + export H5_LDFLAGS="-L$(brew --prefix hdf5)/lib" python -m build --wheel --outdir=./ delocate-wheel trexio-*.whl mv trexio-*.whl ../wheelhouse/ @@ -186,10 +175,10 @@ jobs: steps: - name: Checkout the branch - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: '3.9' diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..65bd022 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,28 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +authors: +- family-names: "Scemama" + given-names: "Anthony" + orcid: "https://orcid.org/0000-0003-4955-7136" +- family-names: "Posenitskiy" + given-names: "Evgeny" + orcid: "https://orcid.org/0000-0002-1623-0594" +title: "TREX I/O library " +version: 2.3.1 +date-released: 2023-04-26 +url: "https://github.com/TREX-CoE/trexio" +preferred-citation: + type: article + authors: + - family-names: "Posenitskiy" + given-names: "Evgeny" + - family-names: "et al." + given-names: "" + doi: "10.1063/5.0148161" + journal: "The Journal of Chemical Physics" + month: 5 + start: 174801 # First page number + title: "TREXIO: A file format and library for quantum chemistry" + issue: 17 + volume: 158 + year: 2023 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bda21c..d680079 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16) # Initialize the CMake project. project(Trexio - VERSION 2.3.1 + VERSION 2.4.0 DESCRIPTION "TREX I/O library" LANGUAGES C Fortran ) diff --git a/ChangeLog b/ChangeLog index 56c8f04..c5b9e36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ CHANGES ======= +2.4 +--- + +- Added state/energy +- Made state/id an index instead of an int + 2.3 --- diff --git a/Makefile.am b/Makefile.am index 2209dad..5b5f2e9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,9 +77,11 @@ endif ORG_FILES = \ src/templates_front/templator_front.org \ src/templates_text/templator_text.org \ - src/templates_hdf5/templator_hdf5.org \ trex.org +if HAVE_HDF5 +ORG_FILES += src/templates_hdf5/templator_hdf5.org +endif src_libtrexio_la_SOURCES = $(trexio_h) $(SOURCES) @@ -160,11 +162,13 @@ EXTRA_DIST += $(trexio_scm) HTML_TANGLED = docs/index.html \ docs/examples.html \ - docs/templator_hdf5.html \ docs/trex.html \ docs/README.html \ docs/templator_front.html \ docs/templator_text.html +if HAVE_HDF5 +HTML_TANGLED += docs/templator_hdf5.html +endif htmldir = $(docdir) # This $(htmlizer) file and the corresponding target rule allow to avoid circular dependency, diff --git a/README.md b/README.md index a313092..2d76146 100644 --- a/README.md +++ b/README.md @@ -208,9 +208,34 @@ For example, the tutorial covering TREXIO basics using benzene molecule as an ex [Documentation generated from TREXIO org-mode files.](https://trex-coe.github.io/trexio/) +## Citation + +The journal article reference describing TREXIO can be cited as follows: + +``` +@article{10.1063/5.0148161, + author = {Posenitskiy, Evgeny and Chilkuri, Vijay Gopal and Ammar, Abdallah and Hapka, Michał and Pernal, Katarzyna and Shinde, Ravindra and Landinez Borda, Edgar Josué and Filippi, Claudia and Nakano, Kosuke and Kohulák, Otto and Sorella, Sandro and de Oliveira Castro, Pablo and Jalby, William and Ríos, Pablo López and Alavi, Ali and Scemama, Anthony}, + title = "{TREXIO: A file format and library for quantum chemistry}", + journal = {The Journal of Chemical Physics}, + volume = {158}, + number = {17}, + year = {2023}, + month = {05}, + issn = {0021-9606}, + doi = {10.1063/5.0148161}, + url = {https://doi.org/10.1063/5.0148161}, + note = {174801}, + eprint = {https://pubs.aip.org/aip/jcp/article-pdf/doi/10.1063/5.0148161/17355866/174801\_1\_5.0148161.pdf}, +} +``` + +Journal paper: [![doi](https://img.shields.io/badge/doi-10.1063/5.0148161-5077AB.svg)](https://doi.org/10.1063/5.0148161) + +ArXiv paper: [![arXiv](https://img.shields.io/badge/arXiv-2302.14793-b31b1b.svg)](https://arxiv.org/abs/2302.14793) + ### Miscellaneous -Note: The code should be compliant with the C99 +The code should be compliant with the C99 [CERT C coding standard](https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-c-coding-standard-2016-v01.pdf). This can be checked with the `cppcheck` tool. diff --git a/configure.ac b/configure.ac index dede482..b8f26a7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([trexio],[2.3.1],[https://github.com/TREX-CoE/trexio/issues]) +AC_INIT([trexio],[2.4.0],[https://github.com/TREX-CoE/trexio/issues]) AC_CONFIG_SRCDIR([Makefile.in]) AC_CONFIG_HEADERS([include/config.h]) @@ -130,8 +130,7 @@ AC_ARG_WITH([hdf5], AS_HELP_STRING([--with-hdf5=PATH], [Path to HDF5 library and headers]), [ with_hdf5="$withval"], [with_hdf5="yes"]) -AS_IF([test "x$with_hdf5" == "xno"], [ - AC_DEFINE([HAVE_HDF5], 0, [Define to 1 if HDF5 is available]) ], +AS_IF([test "x$with_hdf5" == "xno"], [], [test "x$with_hdf5" != "xyes"], [ HDF5_LIBS="-lhdf5" HDF5_PATH="$with_hdf5" diff --git a/python/pytrexio/_version.py b/python/pytrexio/_version.py index f708a9b..3d67cd6 100644 --- a/python/pytrexio/_version.py +++ b/python/pytrexio/_version.py @@ -1 +1 @@ -__version__ = "1.3.2" +__version__ = "2.4.0" diff --git a/python/requirements.txt b/python/requirements.txt index 123153a..0f6ecce 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,4 +1,4 @@ setuptools>=42 pkgconfig -numpy<1.23.0 +numpy<1.24.0 numpy>=1.17.3 diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 5ee7b49..c3f692f 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -1732,6 +1732,12 @@ def _cp(source: str, destination: str): and write it as ~state_id~ attribute. ~trexio_get_state~ returns current state of the ~trexio_t~ file handle. + **Warning:** The ~trexio_set_state~ and ~trexio_get_state~ functions still + use the old convention where the ground state was state ~0~. From version 2.4.0, + the ~state_id~ variable has changed to ~index~ type, so using the more recent + ~trexio_write_state_id~ and ~trexio_read_state_id~ will give different results + in Fortran. + input parameters: ~file~ -- TREXIO file handle. ~state~ -- ~int32_t~ ID of a state (0 for ground state). @@ -2132,24 +2138,35 @@ trexio_read_$group_num$_64 (trexio_t* const file, $group_num_dtype_double$* cons if (num == NULL) return TREXIO_INVALID_ARG_2; if (trexio_has_$group_num$(file) != TREXIO_SUCCESS) return TREXIO_ATTR_MISSING; + trexio_exit_code rc = TREXIO_GROUP_READ_ERROR; + switch (file->back_end) { case TREXIO_TEXT: - return trexio_text_read_$group_num$(file, num); + rc = trexio_text_read_$group_num$(file, num); + break; case TREXIO_HDF5: #ifdef HAVE_HDF5 - return trexio_hdf5_read_$group_num$(file, num); + rc = trexio_hdf5_read_$group_num$(file, num); #else - return TREXIO_BACK_END_MISSING; + rc = TREXIO_BACK_END_MISSING; #endif + break; /* case TREXIO_JSON: - return trexio_json_read_$group_num$(file, num); + rc = trexio_json_read_$group_num$(file, num); + break; ,*/ } - return TREXIO_FAILURE; + if (rc != TREXIO_SUCCESS) return rc; + + /* Handle index type */ + if ($is_index$) { + ,*num += ($group_num_dtype_double$) 1; + } + return rc; } #+end_src @@ -2161,20 +2178,26 @@ trexio_write_$group_num$_64 (trexio_t* const file, const $group_num_dtype_double //if (num <= 0L) return TREXIO_INVALID_NUM; /* this line is uncommented by the generator for dimensioning variables; do NOT remove! */ if (trexio_has_$group_num$(file) == TREXIO_SUCCESS && file->mode != 'u') return TREXIO_ATTR_ALREADY_EXISTS; + /* Handle index type */ + $group_num_dtype_double$ num_write = num; + if ($is_index$) { + num_write -= ($group_num_dtype_double$) 1; + } + switch (file->back_end) { case TREXIO_TEXT: - return trexio_text_write_$group_num$(file, num); + return trexio_text_write_$group_num$(file, num_write); case TREXIO_HDF5: #ifdef HAVE_HDF5 - return trexio_hdf5_write_$group_num$(file, num); + return trexio_hdf5_write_$group_num$(file, num_write); #else return TREXIO_BACK_END_MISSING; #endif /* case TREXIO_JSON: - return trexio_json_write_$group_num$(file, num); + return trexio_json_write_$group_num$(file, num_write); ,*/ } @@ -2219,6 +2242,12 @@ trexio_read_$group_num$_32 (trexio_t* const file, $group_num_dtype_single$* cons if (rc != TREXIO_SUCCESS) return rc; ,*num = ($group_num_dtype_single$) num_64; + + /* Handle index type */ + if ($is_index$) { + ,*num += ($group_num_dtype_single$) 1; + } + return TREXIO_SUCCESS; } #+end_src @@ -2232,20 +2261,26 @@ trexio_write_$group_num$_32 (trexio_t* const file, const $group_num_dtype_single //if (num <= 0) return TREXIO_INVALID_NUM; /* this line is uncommented by the generator for dimensioning variables; do NOT remove! */ if (trexio_has_$group_num$(file) == TREXIO_SUCCESS && file->mode != 'u') return TREXIO_ATTR_ALREADY_EXISTS; + /* Handle index type */ + $group_num_dtype_single$ num_write = num; + if ($is_index$) { + num_write -= ($group_num_dtype_single$) 1; + } + switch (file->back_end) { case TREXIO_TEXT: - return trexio_text_write_$group_num$(file, ($group_num_dtype_double$) num); + return trexio_text_write_$group_num$(file, ($group_num_dtype_double$) num_write); case TREXIO_HDF5: #ifdef HAVE_HDF5 - return trexio_hdf5_write_$group_num$(file, ($group_num_dtype_double$) num); + return trexio_hdf5_write_$group_num$(file, ($group_num_dtype_double$) num_write); #else return TREXIO_BACK_END_MISSING; #endif /* case TREXIO_JSON: - return trexio_json_write_$group_num$(file, ($group_num_dtype_double$) num); + return trexio_json_write_$group_num$(file, ($group_num_dtype_double$) num_write); break; ,*/ } diff --git a/tests/io_dset_int.c b/tests/io_dset_int.c index a349248..137da06 100644 --- a/tests/io_dset_int.c +++ b/tests/io_dset_int.c @@ -13,6 +13,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { // parameters to be written int num = 12; int nucl_index[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + int state_id = 2; /*================= START OF TEST ==================*/ @@ -28,6 +29,10 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { rc = trexio_write_basis_nucleus_index(file, nucl_index); assert (rc == TREXIO_SUCCESS); + // write index attribute in a file + rc = trexio_write_state_id(file, state_id); + assert (rc == TREXIO_SUCCESS); + // close current session rc = trexio_close(file); assert (rc == TREXIO_SUCCESS); @@ -85,8 +90,9 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { trexio_exit_code rc; // parameters to be read - int num; - int* nucl_index; + int num = 0; + int* nucl_index = NULL; + int state_id = 0; /*================= START OF TEST ==================*/ @@ -99,6 +105,11 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { assert (rc == TREXIO_SUCCESS); assert (num == 12); + // read index attribute from the file + rc = trexio_read_state_id(file, &state_id); + assert (rc == TREXIO_SUCCESS); + assert (state_id == 2); + // read numerical dataset from the file nucl_index = (int*) calloc(num, sizeof(int)); rc = trexio_read_basis_nucleus_index(file, nucl_index); diff --git a/tests/io_dset_int_hdf5.c b/tests/io_dset_int_hdf5.c index 81f4592..3237d3e 100644 --- a/tests/io_dset_int_hdf5.c +++ b/tests/io_dset_int_hdf5.c @@ -2,4 +2,3 @@ #define TREXIO_FILE_PREFIX "io_dset_int" #include "test_macros.h" #include "io_dset_int.c" - diff --git a/tests/test_f.f90 b/tests/test_f.f90 index c4fff33..523558c 100644 --- a/tests/test_f.f90 +++ b/tests/test_f.f90 @@ -85,6 +85,7 @@ subroutine test_write(file_name, back_end) integer :: i, j, n_buffers = 5 integer(8) :: buf_size_sparse, buf_size_det, offset + integer :: state_id buf_size_sparse = 100/n_buffers buf_size_det = 50/n_buffers @@ -107,6 +108,7 @@ subroutine test_write(file_name, back_end) ! parameters to be written nucleus_num = 12 + state_id = 2 charge = (/ 6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /) coord = reshape( (/ 0.00000000d0, 1.39250319d0 , 0.00000000d0 , & -1.20594314d0, 0.69625160d0 , 0.00000000d0 , & @@ -182,6 +184,9 @@ subroutine test_write(file_name, back_end) rc = trexio_write_basis_nucleus_index(trex_file, basis_nucleus_index) call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE INDEX') + rc = trexio_write_state_id(trex_file, state_id) + call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE INDEX TYPE') + ! write ao_num which will be used to determine the optimal size of int indices if (trexio_has_ao_num(trex_file) == TREXIO_HAS_NOT) then rc = trexio_write_ao_num(trex_file, ao_num) @@ -302,6 +307,7 @@ subroutine test_read(file_name, back_end) integer*8 :: offset_det_data_read = 5 integer*8 :: determinant_num integer :: int_num + integer :: state_id ! orbital lists integer*4 :: orb_list_up(150) @@ -312,6 +318,7 @@ subroutine test_read(file_name, back_end) num = 12 basis_shell_num = 24 + state_id = 0 index_sparse_ao_2e_int_eri = 0 value_sparse_ao_2e_int_eri = 0.0d0 @@ -379,6 +386,15 @@ subroutine test_read(file_name, back_end) call exit(-1) endif + rc = trexio_read_state_id(trex_file, state_id) + call trexio_assert(rc, TREXIO_SUCCESS) + if (state_id == 2) then + write(*,*) 'SUCCESS READ INDEX TYPE' + else + print *, 'FAILURE INDEX TYPE CHECK' + call exit(-1) + endif + rc = trexio_read_nucleus_point_group(trex_file, sym_str, 10) call trexio_assert(rc, TREXIO_SUCCESS) diff --git a/tools/generator_tools.py b/tools/generator_tools.py index 2cde76f..f8e25db 100644 --- a/tools/generator_tools.py +++ b/tools/generator_tools.py @@ -611,8 +611,13 @@ def get_detailed_num_dict (configuration: dict) -> dict: tmp_dict.update(get_dtype_dict(v2[0], 'num')) if v2[0] in ['int', 'dim', 'dim readonly']: tmp_dict['trex_json_int_type'] = v2[0] + tmp_dict['is_index'] = 'false' + elif v2[0] in ['index']: + tmp_dict['trex_json_int_type'] = v2[0] + tmp_dict['is_index'] = 'file->one_based' else: tmp_dict['trex_json_int_type'] = '' + tmp_dict['is_index'] = 'false' num_dict[tmp_num] = tmp_dict diff --git a/trex.org b/trex.org index ba901a0..101040c 100644 --- a/trex.org +++ b/trex.org @@ -190,13 +190,14 @@ The ~id~ and ~current_label~ attributes need to be specified for each file. #+NAME: state - | Variable | Type | Dimensions | Description | - |-----------------+-------+---------------+---------------------------------------------------------------------------------------------| - | ~num~ | ~dim~ | | Number of states (including the ground state) | - | ~id~ | ~int~ | | Index of the current state (0 is ground state) | - | ~current_label~ | ~str~ | | Label of the current state | - | ~label~ | ~str~ | ~(state.num)~ | Labels of all states | - | ~file_name~ | ~str~ | ~(state.num)~ | Names of the TREXIO files linked to the current one (i.e. containing data for other states) | + | Variable | Type | Dimensions | Description | + |-----------------+---------+---------------+---------------------------------------------------------------------------------------------| + | ~num~ | ~dim~ | | Number of states (including the ground state) | + | ~id~ | ~index~ | | Index of the current state (0 is ground state) | + | ~energy~ | ~float~ | | Energy of the current state | + | ~current_label~ | ~str~ | | Label of the current state | + | ~label~ | ~str~ | ~(state.num)~ | Labels of all states | + | ~file_name~ | ~str~ | ~(state.num)~ | Names of the TREXIO files linked to the current one (i.e. containing data for other states) | #+CALL: json(data=state, title="state") @@ -204,11 +205,12 @@ :results: #+begin_src python :tangle trex.json "state": { - "num" : [ "dim", [] ] - , "id" : [ "int", [] ] - , "current_label" : [ "str", [] ] - , "label" : [ "str", [ "state.num" ] ] - , "file_name" : [ "str", [ "state.num" ] ] + "num" : [ "dim" , [] ] + , "id" : [ "index", [] ] + , "energy" : [ "float", [] ] + , "current_label" : [ "str" , [] ] + , "label" : [ "str" , [ "state.num" ] ] + , "file_name" : [ "str" , [ "state.num" ] ] } , #+end_src :end: