diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 33975b6..f4133b6 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -170,46 +170,47 @@ __trexio_path__ = None ** Error handling #+NAME: table-exit-codes - | Macro | Code | Description | - |----------------------------------+------+----------------------------------------| - | ~TREXIO_FAILURE~ | -1 | 'Unknown failure' | - | ~TREXIO_SUCCESS~ | 0 | 'Success' | - | ~TREXIO_INVALID_ARG_1~ | 1 | 'Invalid argument 1' | - | ~TREXIO_INVALID_ARG_2~ | 2 | 'Invalid argument 2' | - | ~TREXIO_INVALID_ARG_3~ | 3 | 'Invalid argument 3' | - | ~TREXIO_INVALID_ARG_4~ | 4 | 'Invalid argument 4' | - | ~TREXIO_INVALID_ARG_5~ | 5 | 'Invalid argument 5' | - | ~TREXIO_END~ | 6 | 'End of file' | - | ~TREXIO_READONLY~ | 7 | 'Read-only file' | - | ~TREXIO_ERRNO~ | 8 | strerror(errno) | - | ~TREXIO_INVALID_ID~ | 9 | 'Invalid ID' | - | ~TREXIO_ALLOCATION_FAILED~ | 10 | 'Allocation failed' | - | ~TREXIO_HAS_NOT~ | 11 | 'Element absent' | - | ~TREXIO_INVALID_NUM~ | 12 | 'Invalid (negative or 0) dimension' | - | ~TREXIO_ATTR_ALREADY_EXISTS~ | 13 | 'Attribute already exists' | - | ~TREXIO_DSET_ALREADY_EXISTS~ | 14 | 'Dataset already exists' | - | ~TREXIO_OPEN_ERROR~ | 15 | 'Error opening file' | - | ~TREXIO_LOCK_ERROR~ | 16 | 'Error locking file' | - | ~TREXIO_UNLOCK_ERROR~ | 17 | 'Error unlocking file' | - | ~TREXIO_FILE_ERROR~ | 18 | 'Invalid file' | - | ~TREXIO_GROUP_READ_ERROR~ | 19 | 'Error reading group' | - | ~TREXIO_GROUP_WRITE_ERROR~ | 20 | 'Error writing group' | - | ~TREXIO_ELEM_READ_ERROR~ | 21 | 'Error reading element' | - | ~TREXIO_ELEM_WRITE_ERROR~ | 22 | 'Error writing element' | - | ~TREXIO_UNSAFE_ARRAY_DIM~ | 23 | 'Access to memory beyond allocated' | - | ~TREXIO_ATTR_MISSING~ | 24 | 'Attribute does not exist in the file' | - | ~TREXIO_DSET_MISSING~ | 25 | 'Dataset does not exist in the file' | - | ~TREXIO_BACK_END_MISSING~ | 26 | 'Requested back end is disabled' | - | ~TREXIO_INVALID_ARG_6~ | 27 | 'Invalid argument 6' | - | ~TREXIO_INVALID_ARG_7~ | 28 | 'Invalid argument 7' | - | ~TREXIO_INVALID_ARG_8~ | 29 | 'Invalid argument 8' | - | ~TREXIO_INVALID_STR_LEN~ | 30 | 'Invalid max_str_len' | - | ~TREXIO_INT_SIZE_OVERFLOW~ | 31 | 'Possible integer overflow' | - | ~TREXIO_SAFE_MODE~ | 32 | 'Unsafe operation in safe mode' | - | ~TREXIO_INVALID_ELECTRON_NUM~ | 33 | 'Inconsistent number of electrons' | - | ~TREXIO_INVALID_DETERMINANT_NUM~ | 34 | 'Inconsistent number of determinants' | - | ~TREXIO_INVALID_STATE~ | 35 | 'Inconsistent state of the file' | - | ~TREXIO_VERSION_PARSING_ISSUE~ | 36 | 'Failed to parse package_version' | + | Macro | Code | Description | + |----------------------------------+------+------------------------------------------------| + | ~TREXIO_FAILURE~ | -1 | 'Unknown failure' | + | ~TREXIO_SUCCESS~ | 0 | 'Success' | + | ~TREXIO_INVALID_ARG_1~ | 1 | 'Invalid argument 1' | + | ~TREXIO_INVALID_ARG_2~ | 2 | 'Invalid argument 2' | + | ~TREXIO_INVALID_ARG_3~ | 3 | 'Invalid argument 3' | + | ~TREXIO_INVALID_ARG_4~ | 4 | 'Invalid argument 4' | + | ~TREXIO_INVALID_ARG_5~ | 5 | 'Invalid argument 5' | + | ~TREXIO_END~ | 6 | 'End of file' | + | ~TREXIO_READONLY~ | 7 | 'Read-only file' | + | ~TREXIO_ERRNO~ | 8 | strerror(errno) | + | ~TREXIO_INVALID_ID~ | 9 | 'Invalid ID' | + | ~TREXIO_ALLOCATION_FAILED~ | 10 | 'Allocation failed' | + | ~TREXIO_HAS_NOT~ | 11 | 'Element absent' | + | ~TREXIO_INVALID_NUM~ | 12 | 'Invalid (negative or 0) dimension' | + | ~TREXIO_ATTR_ALREADY_EXISTS~ | 13 | 'Attribute already exists' | + | ~TREXIO_DSET_ALREADY_EXISTS~ | 14 | 'Dataset already exists' | + | ~TREXIO_OPEN_ERROR~ | 15 | 'Error opening file' | + | ~TREXIO_LOCK_ERROR~ | 16 | 'Error locking file' | + | ~TREXIO_UNLOCK_ERROR~ | 17 | 'Error unlocking file' | + | ~TREXIO_FILE_ERROR~ | 18 | 'Invalid file' | + | ~TREXIO_GROUP_READ_ERROR~ | 19 | 'Error reading group' | + | ~TREXIO_GROUP_WRITE_ERROR~ | 20 | 'Error writing group' | + | ~TREXIO_ELEM_READ_ERROR~ | 21 | 'Error reading element' | + | ~TREXIO_ELEM_WRITE_ERROR~ | 22 | 'Error writing element' | + | ~TREXIO_UNSAFE_ARRAY_DIM~ | 23 | 'Access to memory beyond allocated' | + | ~TREXIO_ATTR_MISSING~ | 24 | 'Attribute does not exist in the file' | + | ~TREXIO_DSET_MISSING~ | 25 | 'Dataset does not exist in the file' | + | ~TREXIO_BACK_END_MISSING~ | 26 | 'Requested back end is disabled' | + | ~TREXIO_INVALID_ARG_6~ | 27 | 'Invalid argument 6' | + | ~TREXIO_INVALID_ARG_7~ | 28 | 'Invalid argument 7' | + | ~TREXIO_INVALID_ARG_8~ | 29 | 'Invalid argument 8' | + | ~TREXIO_INVALID_STR_LEN~ | 30 | 'Invalid max_str_len' | + | ~TREXIO_INT_SIZE_OVERFLOW~ | 31 | 'Possible integer overflow' | + | ~TREXIO_SAFE_MODE~ | 32 | 'Unsafe operation in safe mode' | + | ~TREXIO_INVALID_ELECTRON_NUM~ | 33 | 'Inconsistent number of electrons' | + | ~TREXIO_INVALID_DETERMINANT_NUM~ | 34 | 'Inconsistent number of determinants' | + | ~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' | # We need to force Emacs not to indent the Python code: # -*- org-src-preserve-indentation: t @@ -253,7 +254,7 @@ return '\n'.join(result) #+RESULTS: - :RESULTS: + :results: #+begin_src c :tangle prefix_front.h :exports none #define TREXIO_FAILURE ((trexio_exit_code) -1) #define TREXIO_SUCCESS ((trexio_exit_code) 0) @@ -293,6 +294,7 @@ return '\n'.join(result) #define TREXIO_INVALID_DETERMINANT_NUM ((trexio_exit_code) 34) #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) #+end_src #+begin_src f90 :tangle prefix_fortran.f90 :exports none @@ -334,6 +336,7 @@ return '\n'.join(result) integer(trexio_exit_code), parameter :: TREXIO_INVALID_DETERMINANT_NUM = 34 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 #+end_src #+begin_src python :tangle prefix_python.py :exports none @@ -376,8 +379,9 @@ return '\n'.join(result) TREXIO_INVALID_DETERMINANT_NUM = 34 TREXIO_INVALID_STATE = 35 TREXIO_VERSION_PARSING_ISSUE = 36 + TREXIO_PHASE_CHANGE = 37 #+end_src - :END: + :end: *** Decoding errors @@ -5571,8 +5575,9 @@ def has_determinant_list(trexio_file) -> bool: ~trexio_to_orbital_list_up_dn~ function does the same but for both up- and down-spin components of the determinant and returns two list of orbitals each corresponding to a different component. - ~trexio_to_bitfield_list~ function converts the list of occupied orbitals (up- or down-spin) - into the corresponding ~int64_t~ bitfield representation of the determinant. + ~trexio_to_bitfield_list~ function converts the list of occupied orbitals (up- or down-spin) into the corresponding ~int64_t~ + bitfield representation of the determinant. If the creation of the bitfield requires a change of sign, the return code is + ~TREXIO_PHASE_CHANGE~. ** C @@ -5606,22 +5611,38 @@ trexio_exit_code trexio_to_bitfield_list (const int32_t* orb_list, if (bit_list == NULL) return TREXIO_INVALID_ARG_3; if (N_int <= 0) return TREXIO_INVALID_ARG_4; - uint32_t i; - uint32_t k; - uint32_t iorb; - for (int32_t j = 0 ; j < N_int ; j++) { bit_list[j] = (bitfield_t) 0; } + uint32_t i; + uint32_t k; + uint32_t iorb; + bitfield_t mask; + uint32_t nswaps = 0; + for (int32_t pos = 0 ; pos < occupied_num ; pos++) { iorb = ((uint32_t) (orb_list[pos] + 1)) - TREXIO_ORBITAL_SHIFT; + + // Set the bit of to one i = (uint32_t) (iorb >> TREXIO_NORB_PER_INT_SHIFT); k = (uint32_t) (iorb & (TREXIO_NORB_PER_INT - 1) ); - bit_list[i] |= ((bitfield_t) 1) << k; + mask = ((bitfield_t) 1) << k; + bit_list[i] |= mask; + + // Check for phase changes + mask = ~(mask - (bitfield_t) 1); + nswaps += popcnt(mask & bit_list[i]) - 1; + for (int j=i+1 ; j < N_int ; ++j) { + if (bit_list[j] != (bitfield_t) 0) + nswaps += popcnt(bit_list[j]); + } } - return TREXIO_SUCCESS; + if ( (nswaps & 1) == 0) + return TREXIO_SUCCESS; + else + return TREXIO_PHASE_CHANGE; } #+end_src diff --git a/tests/test_f.f90 b/tests/test_f.f90 index 89c2c63..c4fff33 100644 --- a/tests/test_f.f90 +++ b/tests/test_f.f90 @@ -508,6 +508,24 @@ subroutine test_read(file_name, back_end) call exit(-1) endif + occ_num_dn = occ_num_up + orb_list_dn(:) = orb_list_up(:) + orb_list_dn(2) = orb_list_up(1) + orb_list_dn(1) = orb_list_up(2) + rc = trexio_to_bitfield_list(orb_list_dn, occ_num_dn, det_list_check, 3) + call trexio_assert(rc, TREXIO_PHASE_CHANGE) + + do i=1,occ_num_dn + orb_list_dn(occ_num_up-i+1) = orb_list_up(i) + enddo + + rc = trexio_to_bitfield_list(orb_list_dn, occ_num_dn, det_list_check, 3) + call trexio_assert(rc, TREXIO_SUCCESS) + + rc = trexio_to_bitfield_list(orb_list_dn, occ_num_dn-1, det_list_check, 3) + call trexio_assert(rc, TREXIO_PHASE_CHANGE) + + rc = trexio_read_mo_num(trex_file, mo_num) call trexio_assert(rc, TREXIO_SUCCESS)