diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index a54725e..c83023a 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -18,12 +18,14 @@ jobs: run: sudo apt-get install emacs autoconf libhdf5-dev - name: Install trexio run: | - wget https://github.com/TREX-CoE/trexio/releases/download/v1.0/trexio-1.0.0.tar.gz - tar -zxf trexio-1.0.0.tar.gz - cd trexio-1.0.0 + # TODO: Update the following link when v1.1 will be released + export VERSION=1.1.0 + wget https://github.com/TREX-CoE/trexio/releases/download/v${VERSION}/trexio-${VERSION}.tar.gz + tar -zxf trexio-${VERSION}.tar.gz + cd trexio-${VERSION} ./configure --prefix=/usr make -j 8 - sudo make install + sudo make install - name: Build run: | ./autogen.sh @@ -34,6 +36,7 @@ jobs: make -j check ldd tests/test_qmckl_ao - name: Archive test log file + if: failure() uses: actions/upload-artifact@v2 with: name: test-report @@ -41,7 +44,14 @@ jobs: - name: Dist test run: | make distcheck - + - name: Archive test log file + if: failure() + uses: actions/upload-artifact@v2 + with: + name: dist-report + path: test-suite.log + + # x86_macos: # # runs-on: macos-latest @@ -59,9 +69,9 @@ jobs: # wget https://github.com/TREX-CoE/trexio/releases/download/v1.0/trexio-1.0.0.tar.gz # tar -zxf trexio-1.0.0.tar.gz # cd trexio-1.0.0 -# ./configure +# ./configure # make -j 8 -# sudo make install +# sudo make install # - name: Run test # run: | # ./autogen.sh diff --git a/Makefile.am b/Makefile.am index 705dcfd..5249142 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,10 +59,13 @@ header_tests = tests/chbrclf.h tests/n2.h qmckl_probes_src = src/qmckl_probes.h src/qmckl_probes.c src/qmckl_probes_f.f90 -fortrandir = $(datadir)/$(PACKAGE_NAME)/fortran/ +fortrandir = $(datadir)/qmckl/fortran/ + dist_fortran_DATA = $(qmckl_f) -AM_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/include +AM_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/include +AM_CPPFLAGS += -DQMCKL_TEST_DIR="\"$(abs_srcdir)/share/qmckl/test_data/\"" + lib_LTLIBRARIES = src/libqmckl.la src_libqmckl_la_SOURCES = $(qmckl_h) $(src_qmckl_f) $(C_FILES) $(F_FILES) $(H_PRIVATE_FUNC_FILES) $(H_PRIVATE_TYPE_FILES) $(header_tests) $(qmckl_probes_src) @@ -71,7 +74,7 @@ export qmckl_f qmckl_h srcdir CLEANFILES+=$(test_qmckl_f) $(src_qmckl_f) $(test_qmckl_o) $(src_qmckl_o) -htmlize_el=share/doc/qmckl/html/htmlize.el +htmlize_el=$(srcdir)/share/doc/qmckl/html/htmlize.el include generated.mk @@ -126,17 +129,17 @@ BUILT_SOURCES = $(C_FILES) $(F_FILES) $(FH_FUNC_FILES) $(FH_TYPE_FILES) $(H_FUNC CLEANFILES += $(BUILT_SOURCES) $(C_TEST_FILES) $(F_TEST_FILES) $(TANGLED_FILES) $(C_TEST_FILES) $(F_TEST_FILES) $(qmckl_f) $(qmckl_h) $(HTML_FILES) $(TEXT_FILES) share/doc/qmckl/html/index.html $(EXPORTED_FILES) $(header_tests) EXTRA_DIST += \ - tools/build_doc.sh \ - tools/build_makefile.py \ - tools/build_qmckl_f.sh \ - tools/build_qmckl_h.sh \ - tools/config_doc.el \ - tools/config_tangle.el \ - tools/init.el \ - tools/install_htmlize.sh \ - tools/lib.org \ - tools/tangle.sh \ - tools/theme.setup + $(srcdir)/tools/build_doc.sh \ + $(srcdir)/tools/build_makefile.py \ + $(srcdir)/tools/build_qmckl_f.sh \ + $(srcdir)/tools/build_qmckl_h.sh \ + $(srcdir)/tools/config_doc.el \ + $(srcdir)/tools/config_tangle.el \ + $(srcdir)/tools/init.el \ + $(srcdir)/tools/install_htmlize.sh \ + $(srcdir)/tools/lib.org \ + $(srcdir)/tools/tangle.sh \ + $(srcdir)/tools/theme.setup ## Silent diff --git a/README.md b/README.md index 97606c1..b2d3bef 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,23 @@ sudo make install sudo make installcheck ``` +## Verificarlo CI + +Since Verificarlo should not be a dependency of QMCkl, all Verificarlo +functions are called only when the support is explicitely enabled (and ignored +by the preprocessor otherwise). To enable vfc_ci support, the library should be +configured with the following command : + +``` +QMCKL_DEVEL=1 ./configure --prefix=$PWD/_install \ --enable-silent-rules --enable-maintainer-mode --enable-vfc_ci --host=x86_64 \ CC="verificarlo-f" FC="verificarlo-f" +``` + +where CC and FC are set to verificarlo-f, and support is explicitely enabled +with the --enable-vfc_ci flag. Configuring the library with the "standard" +command will cause all calls to Verificarlo related functions to be ignored, +and the library will be built as usual. + + ------------------------------ ![European flag](https://trex-coe.eu/sites/default/files/inline-images/euflag.jpg) diff --git a/TODO.org b/TODO.org deleted file mode 100644 index 561860e..0000000 --- a/TODO.org +++ /dev/null @@ -1,48 +0,0 @@ -#+STARTUP: showeverything - -* Set up CI on Travis -* Write tests - -* malloc/free : Parameters for accelerators? -We should define qmckl_malloc and qmckl_free just to give the -possibility of the HPC implementations to define how they allocate the -memory (on CPU or GPU, using alternatives to malloc/free, etc). -A possibility could be to pass the id of a NUMA domain as a parameter of -qmckl_malloc, where the domain id is something obtained from the -context. - - -* TRANSA, TRANSB -* Performance info -* Benchmark interpolation of basis functions -* Complex numbers -* Adjustable number for derivatives (1,2,3) - -* Put pictures -* Make the Makefile part of the documented code ? -* Put the data-flow graph in the code. - -* Verificarlo TODO -These are installation instructions for -verificarlo which needs to be moved to -an appropriate place at some point. -** Compilation and Testing - -The following steps were required to get -the verificarlo version up and running on -an Ubuntu 20.04 laptop. - -1. Compilers - a. clang - For e.g. clang-7 - b. flang - For e.g. flang-7 : Care needs to be taken - that the flang version - is compatible with the - clang version used. - There are known issues - with using oneAPI due - to flang being incompatible - with oneAPI supplied clang. - c. gcc - For e.g. gcc-7 - -2. Environment varibales - a. VFC_BACKENDS - For e.g. `VFC_BACKENDS="libinterflop_ieee.so"` diff --git a/configure.ac b/configure.ac index 2f807f9..ab57775 100644 --- a/configure.ac +++ b/configure.ac @@ -49,9 +49,9 @@ AC_CONFIG_MACRO_DIR([m4]) VERSION_MAJOR=`echo ${PACKAGE_VERSION} | cut -d. -f1` VERSION_MINOR=`echo ${PACKAGE_VERSION} | cut -d. -f2` VERSION_PATCH=`echo ${PACKAGE_VERSION} | cut -d. -f3 | cut -d- -f1` -AC_DEFINE_UNQUOTED(QMCKL_VERSION_MAJOR, [$VERSION_MAJOR], [major version]) -AC_DEFINE_UNQUOTED(QMCKL_VERSION_MINOR, [$VERSION_MINOR], [minor version]) -AC_DEFINE_UNQUOTED(QMCKL_VERSION_PATCH, [$VERSION_PATCH], [patch version]) +AC_DEFINE_UNQUOTED([QMCKL_VERSION_MAJOR], [$VERSION_MAJOR], [major version]) +AC_DEFINE_UNQUOTED([QMCKL_VERSION_MINOR], [$VERSION_MINOR], [minor version]) +AC_DEFINE_UNQUOTED([QMCKL_VERSION_PATCH], [$VERSION_PATCH], [patch version]) AC_SUBST([VERSION_MAJOR]) AC_SUBST([VERSION_MINOR]) AC_SUBST([VERSION_PATCH]) @@ -92,12 +92,30 @@ AC_CHECK_LIB([pthread], [pthread_create]) # OpenMP #AC_ARG_WITH(openmp, [AC_HELP_STRING([--with-openmp],[enable OpenMP])], with_omp=$withval, with_omp=no) #if test "x$with_omp" = xyes; then -# AC_DEFINE([USE_OPENMP], [1], [Define to use OpenMP threading.]) +# AC_DEFINE([HAVE_OPENMP], [1], [Define to use OpenMP threading.]) # AX_OPENMP([], # [AC_MSG_ERROR([Could not find OpenMP flags; configure with --without-openmp])]) # CFLAGS="${CFLAGS} ${OPENMP_CFLAGS}" #fi +# TREXIO + +AC_ARG_WITH(trexio, [AC_HELP_STRING([--without-trexio],[disable support for TREXIO])], + with_trexio=$withval, with_trexio=yes) + +AS_IF([test "x$with_trexio" != xno], [ + AC_DEFINE([HAVE_TREXIO], [1], [Define if your have libtrexio]) + ARGS="${ARGS} trexio" + AC_CHECK_LIB([trexio], [trexio_open], + [], + [AS_IF([test "x$with_trexio" != xcheck], + [PKG_CHECK_MODULES([TREXIO], [trexio]) ]) + ]) +]) + +PKG_CFLAGS="$PKG_CFLAGS $TREXIO_CFLAGS" +PKG_LIBS="$PKG_LIBS $TREXIO_LIBS" + ## BLAS #AX_BLAS([], [AC_MSG_ERROR([BLAS was not found.])]) @@ -222,8 +240,9 @@ fi #PKG-CONFIG #mkl-dynamic-lp64-seq -LIBS="${LAPACK_LIBS} ${BLAS_LIBS} ${LIBS}" -PKG_LIBS="${PKG_LIBS} ${LIBS}" +PKG_LIBS="$PKG_LIBS $LIBS" +LIBS="$LAPACK_LIBS $BLAS_LIBS $PKG_LIBS" +CFLAGS="$CFLAGS $PKG_CFLAGS" AC_SUBST([PKG_LIBS]) AC_SUBST([PKG_CFLAGS]) AC_SUBST([HAS_CPPCHECK]) diff --git a/include/config.h.in b/include/config.h.in deleted file mode 100644 index 01facda..0000000 --- a/include/config.h.in +++ /dev/null @@ -1,153 +0,0 @@ -/* include/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to turn on debugging checks */ -#undef DEBUG - -/* Define when using the profiler tool */ -#undef ENABLE_PROF - -/* Define to 1 if your Fortran compiler doesn't accept -c and -o together. */ -#undef FC_NO_MINUS_C_MINUS_O - -/* Define to 1 if you have the header file. */ -#undef HAVE_ASSERT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ERRNO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `efence' library (-lefence). */ -#undef HAVE_LIBEFENCE - -/* Define to 1 if you have the `m' library (-lm). */ -#undef HAVE_LIBM - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#undef HAVE_LIBPTHREAD - -/* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MATH_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_PTHREAD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDBOOL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if the system has the type `_Bool'. */ -#undef HAVE__BOOL - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Define to use debugging malloc/free */ -#undef MALLOC_TRACE - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* major version */ -#undef QMCKL_VERSION_MAJOR - -/* minor version */ -#undef QMCKL_VERSION_MINOR - -/* patch version */ -#undef QMCKL_VERSION_PATCH - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT32_T - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT64_T - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef int32_t - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef int64_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef uint32_t - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef uint64_t diff --git a/org/qmckl_ao.org b/org/qmckl_ao.org index c18d3fa..153cd4d 100644 --- a/org/qmckl_ao.org +++ b/org/qmckl_ao.org @@ -238,7 +238,10 @@ qmckl_exit_code qmckl_init_ao_basis(qmckl_context context); qmckl_exit_code qmckl_init_ao_basis(qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return false; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_init_ao_basis", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -255,29 +258,9 @@ qmckl_exit_code qmckl_init_ao_basis(qmckl_context context) { ** Access functions - #+begin_src c :comments org :tangle (eval h_private_func) :exports none -char qmckl_get_ao_basis_type (const qmckl_context context); -int64_t qmckl_get_ao_basis_shell_num (const qmckl_context context); -int64_t qmckl_get_ao_basis_prim_num (const qmckl_context context); -int64_t qmckl_get_ao_basis_ao_num (const qmckl_context context); -int64_t* qmckl_get_ao_basis_nucleus_index (const qmckl_context context); -int64_t* qmckl_get_ao_basis_nucleus_shell_num(const qmckl_context context); -int32_t* qmckl_get_ao_basis_shell_ang_mom (const qmckl_context context); -int64_t* qmckl_get_ao_basis_shell_prim_num (const qmckl_context context); -int64_t* qmckl_get_ao_basis_shell_prim_index (const qmckl_context context); -double* qmckl_get_ao_basis_shell_factor (const qmckl_context context); -double* qmckl_get_ao_basis_exponent (const qmckl_context context); -double* qmckl_get_ao_basis_coefficient (const qmckl_context context); -double* qmckl_get_ao_basis_prim_factor (const qmckl_context context); -double* qmckl_get_ao_basis_ao_factor (const qmckl_context context); - #+end_src - - When all the data for the AOs have been provided, the following - function returns ~true~. - - #+begin_src c :comments org :tangle (eval h_func) -bool qmckl_ao_basis_provided (const qmckl_context context); - #+end_src + In the following functions, when an array is passed as an argument + the size of the array should be also passed to check that the array + is large enough to accept the data. #+NAME:post #+begin_src c :exports none @@ -286,11 +269,23 @@ if ( (ctx->ao_basis.uninitialized & mask) != 0) { } #+end_src + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_type (const qmckl_context context, + char* const type); + #+end_src + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none -char qmckl_get_ao_basis_type (const qmckl_context context) { +qmckl_exit_code +qmckl_get_ao_basis_type (const qmckl_context context, + char* const basis_type) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (char) 0; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_type", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -299,17 +294,37 @@ char qmckl_get_ao_basis_type (const qmckl_context context) { int32_t mask = 1; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return (char) 0; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_type", + NULL); + } assert (ctx->ao_basis.type != (char) 0); - return ctx->ao_basis.type; + + ,*basis_type = ctx->ao_basis.type; + return QMCKL_SUCCESS; } + #+end_src -int64_t qmckl_get_ao_basis_shell_num (const qmckl_context context) { + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_num (const qmckl_context context, + int64_t* const shell_num); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_num (const qmckl_context context, + int64_t* const shell_num) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_factor", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -318,17 +333,35 @@ int64_t qmckl_get_ao_basis_shell_num (const qmckl_context context) { int32_t mask = 1 << 1; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_shell_num", + NULL); } assert (ctx->ao_basis.shell_num > (int64_t) 0); - return ctx->ao_basis.shell_num; + ,*shell_num = ctx->ao_basis.shell_num; + return QMCKL_SUCCESS; } + #+end_src -int64_t qmckl_get_ao_basis_prim_num (const qmckl_context context) { + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_prim_num (const qmckl_context context, + int64_t* const prim_num); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_prim_num (const qmckl_context context, + int64_t* const prim_num) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_prim_num", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -337,17 +370,38 @@ int64_t qmckl_get_ao_basis_prim_num (const qmckl_context context) { int32_t mask = 1 << 2; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_prim_num", + NULL); } assert (ctx->ao_basis.prim_num > (int64_t) 0); - return ctx->ao_basis.prim_num; + + ,*prim_num = ctx->ao_basis.prim_num; + return QMCKL_SUCCESS; } + #+end_src -int64_t* qmckl_get_ao_basis_nucleus_shell_num (const qmckl_context context) { + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_nucleus_shell_num (const qmckl_context context, + int64_t* const nucleus_shell_num, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_nucleus_shell_num (const qmckl_context context, + int64_t* const nucleus_shell_num, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_nucleus_shell_num", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -356,16 +410,51 @@ int64_t* qmckl_get_ao_basis_nucleus_shell_num (const qmckl_context context) { int32_t mask = 1 << 3; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_nucleus_shell_num", + NULL); + } + + if (nucleus_shell_num == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_nucleus_shell_num", + "NULL pointer"); + } + + if (size_max < ctx->nucleus.num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_nucleus_shell_num", + "Array too small. Expected nucl_num"); } assert (ctx->ao_basis.nucleus_shell_num != NULL); - return ctx->ao_basis.nucleus_shell_num ; + memcpy(nucleus_shell_num, ctx->ao_basis.nucleus_shell_num, ctx->nucleus.num * sizeof(int64_t)); + return QMCKL_SUCCESS; } -int64_t* qmckl_get_ao_basis_nucleus_index (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_nucleus_index (const qmckl_context context, + int64_t* const nucleus_index, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_nucleus_index (const qmckl_context context, + int64_t* const nucleus_index, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_nucleus_index", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -374,17 +463,52 @@ int64_t* qmckl_get_ao_basis_nucleus_index (const qmckl_context context) { int32_t mask = 1 << 4; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_nucleus_index", + NULL); + } + + if (nucleus_index == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_nucleus_index", + "NULL pointer"); + } + + if (size_max < ctx->nucleus.num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_nucleus_index", + "Array too small. Expected shell_num"); } assert (ctx->ao_basis.nucleus_index != NULL); - return ctx->ao_basis.nucleus_index ; + memcpy(nucleus_index, ctx->ao_basis.nucleus_index, ctx->nucleus.num * sizeof(int64_t)); + return QMCKL_SUCCESS; } -int32_t* qmckl_get_ao_basis_shell_ang_mom (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_ang_mom (const qmckl_context context, + int32_t* const shell_ang_mom, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_ang_mom (const qmckl_context context, + int32_t* const shell_ang_mom, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_ang_mom", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -393,17 +517,52 @@ int32_t* qmckl_get_ao_basis_shell_ang_mom (const qmckl_context context) { int32_t mask = 1 << 5; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_shell_ang_mom", + NULL); + } + + if (shell_ang_mom == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_shell_ang_mom", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.shell_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_shell_ang_mom", + "Array too small. Expected shell_num"); } assert (ctx->ao_basis.shell_ang_mom != NULL); - return ctx->ao_basis.shell_ang_mom; + memcpy(shell_ang_mom, ctx->ao_basis.shell_ang_mom, ctx->ao_basis.shell_num * sizeof(int32_t)); + return QMCKL_SUCCESS; } -int64_t* qmckl_get_ao_basis_shell_prim_num (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_prim_num (const qmckl_context context, + int64_t* const shell_prim_num, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_prim_num (const qmckl_context context, + int64_t* const shell_prim_num, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_prim_num", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -412,17 +571,52 @@ int64_t* qmckl_get_ao_basis_shell_prim_num (const qmckl_context context) { int32_t mask = 1 << 6; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_shell_prim_num", + NULL); + } + + if (shell_prim_num == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_shell_prim_num", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.shell_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_shell_prim_num", + "Array too small. Expected shell_num"); } assert (ctx->ao_basis.shell_prim_num != NULL); - return ctx->ao_basis.shell_prim_num; + memcpy(shell_prim_num, ctx->ao_basis.shell_prim_num, ctx->ao_basis.shell_num * sizeof(int64_t)); + return QMCKL_SUCCESS; } -int64_t* qmckl_get_ao_basis_shell_prim_index (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_prim_index (const qmckl_context context, + int64_t* const shell_prim_index, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_prim_index (const qmckl_context context, + int64_t* const shell_prim_index, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_prim_index", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -431,17 +625,50 @@ int64_t* qmckl_get_ao_basis_shell_prim_index (const qmckl_context context) { int32_t mask = 1 << 7; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_shell_prim_index", + NULL); + } + + if (shell_prim_index == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_shell_prim_index", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.shell_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_shell_prim_index", + "Array too small. Expected shell_num"); } assert (ctx->ao_basis.shell_prim_index != NULL); - return ctx->ao_basis.shell_prim_index; + memcpy(shell_prim_index, ctx->ao_basis.shell_prim_index, ctx->ao_basis.shell_num * sizeof(int64_t)); + return QMCKL_SUCCESS; } + #+end_src + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_factor (const qmckl_context context, + double* const shell_factor, + const int64_t size_max); + #+end_src -double* qmckl_get_ao_basis_shell_factor (const qmckl_context context) { + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_shell_factor (const qmckl_context context, + double* const shell_factor, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_factor", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -450,37 +677,104 @@ double* qmckl_get_ao_basis_shell_factor (const qmckl_context context) { int32_t mask = 1 << 8; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_shell_factor", + NULL); + } + + if (shell_factor == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_shell_factor", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.shell_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_shell_factor", + "Array too small. Expected shell_num"); } assert (ctx->ao_basis.shell_factor != NULL); - return ctx->ao_basis.shell_factor; + memcpy(shell_factor, ctx->ao_basis.shell_factor, ctx->ao_basis.shell_num * sizeof(double)); + return QMCKL_SUCCESS; } -double* qmckl_get_ao_basis_exponent (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_exponent (const qmckl_context context, + double* const exponent, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_exponent (const qmckl_context context, + double* const exponent, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_exponent", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; assert (ctx != NULL); - int32_t mask = 1 << 9; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_exponent", + NULL); + } + + if (exponent == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_exponent", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.prim_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_exponent", + "Array too small. Expected prim_num"); } assert (ctx->ao_basis.exponent != NULL); - return ctx->ao_basis.exponent; + memcpy(exponent, ctx->ao_basis.exponent, ctx->ao_basis.prim_num * sizeof(double)); + return QMCKL_SUCCESS; } + #+end_src + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_coefficient (const qmckl_context context, + double* const coefficient, + const int64_t size_max); + #+end_src -double* qmckl_get_ao_basis_coefficient (const qmckl_context context) { + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_coefficient (const qmckl_context context, + double* const coefficient, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_coefficient", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -489,17 +783,51 @@ double* qmckl_get_ao_basis_coefficient (const qmckl_context context) { int32_t mask = 1 << 10; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_coefficient", + NULL); } + if (coefficient == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_coefficient", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.prim_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_coefficient", + "Array too small. Expected prim_num"); + } assert (ctx->ao_basis.coefficient != NULL); - return ctx->ao_basis.coefficient; + memcpy(coefficient, ctx->ao_basis.coefficient, ctx->ao_basis.prim_num * sizeof(double)); + return QMCKL_SUCCESS; } -double* qmckl_get_ao_basis_prim_factor (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_prim_factor (const qmckl_context context, + double* const prim_factor, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_prim_factor (const qmckl_context context, + double* const prim_factor, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_prim_factor", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -508,17 +836,50 @@ double* qmckl_get_ao_basis_prim_factor (const qmckl_context context) { int32_t mask = 1 << 11; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_prim_factor", + NULL); + } + + if (prim_factor == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_prim_factor", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.prim_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_prim_factor", + "Array too small. Expected prim_num"); } assert (ctx->ao_basis.prim_factor != NULL); - return ctx->ao_basis.prim_factor; + memcpy(prim_factor, ctx->ao_basis.prim_factor, ctx->ao_basis.prim_num * sizeof(double)); + return QMCKL_SUCCESS; } -int64_t qmckl_get_ao_basis_ao_num (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_ao_basis_ao_num (const qmckl_context context, + int64_t* const ao_num); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_ao_num (const qmckl_context context, + int64_t* const ao_num) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_ao_num", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -527,17 +888,32 @@ int64_t qmckl_get_ao_basis_ao_num (const qmckl_context context) { int32_t mask = 1 << 12; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_ao_num", + NULL); } assert (ctx->ao_basis.ao_num > (int64_t) 0); - return ctx->ao_basis.ao_num; + + *ao_num = ctx->ao_basis.ao_num; + return QMCKL_SUCCESS; } -double* qmckl_get_ao_basis_ao_factor (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none +qmckl_exit_code +qmckl_get_ao_basis_ao_factor (const qmckl_context context, + double* const ao_factor, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return NULL; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_ao_factor", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -546,14 +922,46 @@ double* qmckl_get_ao_basis_ao_factor (const qmckl_context context) { int32_t mask = 1 << 13; if ( (ctx->ao_basis.uninitialized & mask) != 0) { - return NULL; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_ao_basis_ao_factor", + NULL); + } + + if (ao_factor == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_ao_basis_ao_factor", + "NULL pointer"); + } + + if (size_max < ctx->ao_basis.ao_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_ao_basis_ao_factor", + "Array too small. Expected ao_num"); } assert (ctx->ao_basis.ao_factor != NULL); - return ctx->ao_basis.ao_factor; + memcpy(ao_factor, ctx->ao_basis.ao_factor, ctx->ao_basis.ao_num * sizeof(double)); + return QMCKL_SUCCESS; } + #+end_src + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code qmckl_get_ao_basis_ao_factor (const qmckl_context context, + double* const ao_factor, + const int64_t size_max); + #+end_src + When all the data for the AOs have been provided, the following + function returns ~true~. + + #+begin_src c :comments org :tangle (eval h_func) +bool qmckl_ao_basis_provided (const qmckl_context context); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none bool qmckl_ao_basis_provided(const qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { @@ -565,9 +973,6 @@ bool qmckl_ao_basis_provided(const qmckl_context context) { return ctx->ao_basis.provided; } - - - #+end_src ** Initialization functions @@ -596,7 +1001,10 @@ qmckl_exit_code qmckl_set_ao_basis_cartesian (qmckl_context context, con #+NAME:pre2 #+begin_src c :exports none if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_*", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -630,8 +1038,9 @@ qmckl_exit_code qmckl_set_ao_basis_type(qmckl_context context, const char t) { <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_shell_num(qmckl_context context, const int64_t shell_num) { <> @@ -642,7 +1051,7 @@ qmckl_exit_code qmckl_set_ao_basis_shell_num(qmckl_context context, const int64_ "shell_num <= 0"); } - int64_t prim_num = qmckl_get_ao_basis_prim_num(context); + const int64_t prim_num = ctx->ao_basis.prim_num; if (0L < prim_num && prim_num < shell_num) { return qmckl_failwith( context, @@ -656,8 +1065,9 @@ qmckl_exit_code qmckl_set_ao_basis_shell_num(qmckl_context context, const int64_ <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_prim_num(qmckl_context context, const int64_t prim_num) { <> @@ -668,7 +1078,14 @@ qmckl_exit_code qmckl_set_ao_basis_prim_num(qmckl_context context, const int64_ "prim_num must be positive"); } - int64_t shell_num = qmckl_get_ao_basis_shell_num(context); + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { + return qmckl_failwith( context, + QMCKL_FAILURE, + "qmckl_set_ao_basis_shell_num", + "shell_num is not set"); + } if (prim_num < shell_num) { return qmckl_failwith( context, @@ -682,15 +1099,17 @@ qmckl_exit_code qmckl_set_ao_basis_prim_num(qmckl_context context, const int64_ <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_nucleus_shell_num(qmckl_context context, const int64_t* nucleus_shell_num) { <> int32_t mask = 1 << 3; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); - if (shell_num == 0L) { + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_nucleus_shell_num", @@ -723,14 +1142,17 @@ qmckl_exit_code qmckl_set_ao_basis_nucleus_shell_num(qmckl_context context, con <> } + #+end_src + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_nucleus_index(qmckl_context context, const int64_t* nucleus_index) { <> int32_t mask = 1 << 4; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); - if (shell_num == 0L) { + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_nucleus_index", @@ -763,14 +1185,16 @@ qmckl_exit_code qmckl_set_ao_basis_nucleus_index(qmckl_context context, const i <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_shell_ang_mom(qmckl_context context, const int32_t* shell_ang_mom) { <> int32_t mask = 1 << 5; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); + const int64_t shell_num = ctx->ao_basis.shell_num; + if (shell_num == 0L) { return qmckl_failwith( context, QMCKL_FAILURE, @@ -805,15 +1229,17 @@ qmckl_exit_code qmckl_set_ao_basis_shell_ang_mom(qmckl_context context, const i <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_shell_prim_num(qmckl_context context, const int64_t* shell_prim_num) { <> int32_t mask = 1 << 6; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); - if (shell_num == 0L) { + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_shell_prim_num", @@ -847,15 +1273,17 @@ qmckl_exit_code qmckl_set_ao_basis_shell_prim_num(qmckl_context context, const <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_shell_prim_index(qmckl_context context, const int64_t* shell_prim_index) { <> int32_t mask = 1 << 7; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); - if (shell_num == 0L) { + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_shell_prim_index", @@ -888,15 +1316,17 @@ qmckl_exit_code qmckl_set_ao_basis_shell_prim_index(qmckl_context context, cons <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_shell_factor(qmckl_context context, const double* shell_factor) { <> int32_t mask = 1 << 8; - const int64_t shell_num = qmckl_get_ao_basis_shell_num(context); - if (shell_num == 0L) { + const int64_t shell_num = ctx->ao_basis.shell_num; + + if (shell_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_shell_factor", @@ -930,14 +1360,17 @@ qmckl_exit_code qmckl_set_ao_basis_shell_factor(qmckl_context context, const do <> } + #+end_src + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_exponent(qmckl_context context, const double* exponent) { <> int32_t mask = 1 << 9; - const int64_t prim_num = qmckl_get_ao_basis_prim_num(context); - if (prim_num == 0L) { + const int64_t prim_num = ctx->ao_basis.prim_num; + + if (prim_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_exponent", @@ -970,14 +1403,17 @@ qmckl_exit_code qmckl_set_ao_basis_exponent(qmckl_context context, const double <> } + #+end_src + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_coefficient(qmckl_context context, const double* coefficient) { <> int32_t mask = 1 << 10; - const int64_t prim_num = qmckl_get_ao_basis_prim_num(context); - if (prim_num == 0L) { + const int64_t prim_num = ctx->ao_basis.prim_num; + + if (prim_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_coefficient", @@ -1010,15 +1446,17 @@ qmckl_exit_code qmckl_set_ao_basis_coefficient(qmckl_context context, const dou <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_prim_factor(qmckl_context context, const double* prim_factor) { <> int32_t mask = 1 << 11; - const int64_t prim_num = qmckl_get_ao_basis_prim_num(context); - if (prim_num == 0L) { + const int64_t prim_num = ctx->ao_basis.prim_num; + + if (prim_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_prim_factor", @@ -1052,8 +1490,9 @@ qmckl_exit_code qmckl_set_ao_basis_prim_factor(qmckl_context context, const dou <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_ao_num(qmckl_context context, const int64_t ao_num) { <> @@ -1064,7 +1503,13 @@ qmckl_exit_code qmckl_set_ao_basis_ao_num(qmckl_context context, const int64_t "ao_num must be positive"); } - int64_t shell_num = qmckl_get_ao_basis_shell_num(context); + const int64_t shell_num = ctx->ao_basis.shell_num; + if (shell_num <= 0L) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_set_ao_basis_shell_num", + "shell_num is not set"); + } if (ao_num < shell_num) { return qmckl_failwith( context, @@ -1078,15 +1523,17 @@ qmckl_exit_code qmckl_set_ao_basis_ao_num(qmckl_context context, const int64_t <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_ao_factor(qmckl_context context, const double* ao_factor) { <> int32_t mask = 1 << 13; - const int64_t ao_num = qmckl_get_ao_basis_ao_num(context); - if (ao_num == 0L) { + const int64_t ao_num = ctx->ao_basis.ao_num; + + if (ao_num <= 0L) { return qmckl_failwith( context, QMCKL_FAILURE, "qmckl_set_ao_basis_ao_factor", @@ -1120,8 +1567,9 @@ qmckl_exit_code qmckl_set_ao_basis_ao_factor(qmckl_context context, const doubl <> } + #+end_src - + #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none qmckl_exit_code qmckl_set_ao_basis_cartesian(qmckl_context context, const bool t) { <> @@ -1148,16 +1596,18 @@ qmckl_exit_code qmckl_finalize_basis(qmckl_context context); qmckl_exit_code qmckl_finalize_basis(qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_INVALID_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_finalize_basis", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; assert (ctx != NULL); int64_t nucl_num = 0; - qmckl_exit_code rc = QMCKL_FAILURE; - rc = qmckl_get_nucleus_num(context, &nucl_num); + qmckl_exit_code rc = qmckl_get_nucleus_num(context, &nucl_num); if (rc != QMCKL_SUCCESS) return rc; /* nucleus_prim_index */ @@ -1536,64 +1986,97 @@ double * ao_factor_test ; char typ_test ; -typ_test = qmckl_get_ao_basis_type (context); +rc = qmckl_get_ao_basis_type (context, &typ_test); +assert (rc == QMCKL_SUCCESS); assert(typ == typ_test); -shell_num_test = qmckl_get_ao_basis_shell_num (context); +rc = qmckl_get_ao_basis_shell_num (context, &shell_num_test); +assert (rc == QMCKL_SUCCESS); assert(shell_num == shell_num_test); -prim_num_test = qmckl_get_ao_basis_prim_num (context); +rc = qmckl_get_ao_basis_prim_num (context, &prim_num_test); +assert (rc == QMCKL_SUCCESS); assert(prim_num == prim_num_test); -nucleus_index_test = qmckl_get_ao_basis_nucleus_index (context); +nucleus_index_test = (int64_t*) malloc (nucl_num * sizeof(int64_t)); +rc = qmckl_get_ao_basis_nucleus_index (context, nucleus_index_test, nucl_num); +assert (rc == QMCKL_SUCCESS); for (int64_t i=0 ; i < nucl_num ; ++i) { assert(nucleus_index_test[i] == nucleus_index[i]); } +free(nucleus_index_test); + +nucleus_shell_num_test = (int64_t*) malloc ( nucl_num * sizeof(int64_t)); +rc = qmckl_get_ao_basis_nucleus_shell_num (context, nucleus_shell_num_test, nucl_num); +assert (rc == QMCKL_SUCCESS); -nucleus_shell_num_test = qmckl_get_ao_basis_nucleus_shell_num (context); for (int64_t i=0 ; i < nucl_num ; ++i) { assert(nucleus_shell_num_test[i] == nucleus_shell_num[i]); } -shell_ang_mom_test = qmckl_get_ao_basis_shell_ang_mom (context); +shell_ang_mom_test = (int32_t*) malloc ( shell_num * sizeof(int32_t)); +rc = qmckl_get_ao_basis_shell_ang_mom (context, shell_ang_mom_test, shell_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < shell_num ; ++i) { assert(shell_ang_mom_test[i] == shell_ang_mom[i]); } -shell_factor_test = qmckl_get_ao_basis_shell_factor (context); +shell_factor_test = (double*) malloc ( shell_num * sizeof(double)); +rc = qmckl_get_ao_basis_shell_factor (context, shell_factor_test, shell_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < shell_num ; ++i) { assert(shell_factor_test[i] == shell_factor[i]); } -shell_prim_num_test = qmckl_get_ao_basis_shell_prim_num (context); +shell_prim_num_test = (int64_t*) malloc ( shell_num * sizeof(int64_t)); +rc = qmckl_get_ao_basis_shell_prim_num (context, shell_prim_num_test, shell_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < shell_num ; ++i) { assert(shell_prim_num_test[i] == shell_prim_num[i]); } -shell_prim_index_test = qmckl_get_ao_basis_shell_prim_index (context); +shell_prim_index_test = (int64_t*) malloc ( shell_num * sizeof(int64_t)); +rc = qmckl_get_ao_basis_shell_prim_index (context, shell_prim_index_test, shell_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < shell_num ; ++i) { assert(shell_prim_index_test[i] == shell_prim_index[i]); } -exponent_test = qmckl_get_ao_basis_exponent(context); +exponent_test = (double*) malloc ( prim_num * sizeof(double)); +rc = qmckl_get_ao_basis_exponent(context, exponent_test, prim_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < prim_num ; ++i) { assert(exponent_test[i] == exponent[i]); } -coefficient_test = qmckl_get_ao_basis_coefficient(context); +coefficient_test = (double*) malloc ( prim_num * sizeof(double)); +rc = qmckl_get_ao_basis_coefficient(context, coefficient_test, prim_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < prim_num ; ++i) { assert(coefficient_test[i] == coefficient[i]); } -prim_factor_test = qmckl_get_ao_basis_prim_factor (context); +prim_factor_test = (double*) malloc ( prim_num * sizeof(double)); +rc = qmckl_get_ao_basis_prim_factor (context, prim_factor_test, prim_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < prim_num ; ++i) { assert(prim_factor_test[i] == prim_factor[i]); } -ao_num_test = qmckl_get_ao_basis_ao_num(context); +rc = qmckl_get_ao_basis_ao_num(context, &ao_num_test); assert(ao_num == ao_num_test); -ao_factor_test = qmckl_get_ao_basis_ao_factor (context); +ao_factor_test = (double*) malloc ( ao_num * sizeof(double)); +rc = qmckl_get_ao_basis_ao_factor (context, ao_factor_test, ao_num); +assert (rc == QMCKL_SUCCESS); + for (int64_t i=0 ; i < ao_num ; ++i) { assert(ao_factor_test[i] == ao_factor[i]); } @@ -1745,12 +2228,9 @@ end function qmckl_ao_gaussian_vgl #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) use qmckl - use qmckl_probes_f - implicit none integer(c_int64_t), intent(in), value :: context - logical(C_BOOL) :: vfc_err integer*8 :: n, ldv, j, i double precision :: X(3), R(3), Y(3), r2 @@ -1759,13 +2239,6 @@ integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) epsilon = qmckl_get_numprec_epsilon(context) -#ifdef VFC_CI - ! Multplying epsilon by 16 = 2^4 is equivalent to asking 4 significant digits - ! less. This makes sense because we are adding noise with MCA so we can't be - ! as strict on the accuracy target. - epsilon = epsilon * 16 -#endif - X = (/ 1.1 , 2.2 , 3.3 /) R = (/ 0.1 , 1.2 , -2.3 /) Y(:) = X(:) - R(:) @@ -1782,29 +2255,10 @@ integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) test_qmckl_ao_gaussian_vgl = & qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "gaussian_vgl_2_1"//C_NULL_CHAR, & - DBLE(VGL(2,1)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "gaussian_vgl_2_2"//C_NULL_CHAR, & - DBLE(VGL(2,2)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "gaussian_vgl_2_3"//C_NULL_CHAR, & - DBLE(VGL(2,3)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "gaussian_vgl_2_4"//C_NULL_CHAR, & - DBLE(VGL(2,4)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "gaussian_vgl_2_5"//C_NULL_CHAR, & - DBLE(VGL(2,5)), DBLE(0), DBLE(epsilon)) - -#ifndef VFC_CI if (test_qmckl_ao_gaussian_vgl /= 0) return -#endif test_qmckl_ao_gaussian_vgl = -1 -#ifndef VFC_CI do i=1,n test_qmckl_ao_gaussian_vgl = -11 if (dabs(1.d0 - VGL(i,1) / (& @@ -1831,7 +2285,6 @@ integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) A(i) * (4.d0*r2*A(i) - 6.d0) * dexp(-A(i) * r2) & )) > epsilon ) return end do -#endif test_qmckl_ao_gaussian_vgl = 0 @@ -1858,7 +2311,10 @@ qmckl_exit_code qmckl_get_ao_basis_primitive_vgl(qmckl_context context, double* qmckl_exit_code qmckl_get_ao_basis_primitive_vgl(qmckl_context context, double* const primitive_vgl) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_primitive_vgl", + NULL); } qmckl_exit_code rc; @@ -1887,7 +2343,10 @@ qmckl_exit_code qmckl_provide_ao_basis_primitive_vgl(qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_provide_get_ao_basis_primitive_vgl", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -2203,7 +2662,10 @@ qmckl_exit_code qmckl_get_ao_basis_shell_vgl(qmckl_context context, double* cons qmckl_exit_code qmckl_get_ao_basis_shell_vgl(qmckl_context context, double* const shell_vgl) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_basis_shell_vgl", + NULL); } qmckl_exit_code rc; @@ -2246,7 +2708,10 @@ qmckl_exit_code qmckl_provide_ao_basis_shell_vgl(qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_provide_ao_basis_shell_vgl", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -2255,7 +2720,7 @@ qmckl_exit_code qmckl_provide_ao_basis_shell_vgl(qmckl_context context) if (!ctx->ao_basis.provided) { return qmckl_failwith( context, QMCKL_NOT_PROVIDED, - "qmckl_ao_basis_shell_vgl", + "qmckl_provide_ao_basis_shell_vgl", NULL); } @@ -2774,12 +3239,8 @@ end function qmckl_ao_power_f #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) use qmckl - use qmckl_probes_f - implicit none - logical(C_BOOL) :: vfc_err - integer(qmckl_context), intent(in), value :: context integer*8 :: n, LDP @@ -2790,13 +3251,6 @@ integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) epsilon = qmckl_get_numprec_epsilon(context) -#ifdef VFC_CI - ! Multplying epsilon by 16 = 2^4 is equivalent to asking 4 significant digits - ! less. This makes sense because we are adding noise with MCA so we can't be - ! as strict on the accuracy target. - epsilon = epsilon * 16 -#endif - n = 100; LDP = 10; @@ -2808,15 +3262,10 @@ integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) end do test_qmckl_ao_power = qmckl_ao_power(context, n, X, LMAX, P, LDP) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "power_2_2"//C_NULL_CHAR, & - DBLE(P(2,2)), DBLE(0), DBLE(epsilon)) - if (test_qmckl_ao_power /= QMCKL_SUCCESS) return test_qmckl_ao_power = QMCKL_FAILURE -#ifndef VFC_CI do j=1,n do i=1,LMAX(j) if ( X(j)**i == 0.d0 ) then @@ -2826,7 +3275,6 @@ integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) end if end do end do -#endif test_qmckl_ao_power = QMCKL_SUCCESS deallocate(X,P,LMAX) @@ -3119,12 +3567,9 @@ end function qmckl_ao_polynomial_vgl_f #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_polynomial_vgl(context) bind(C) use qmckl - use qmckl_probes_f - implicit none integer(c_int64_t), intent(in), value :: context - logical(C_BOOL) :: vfc_err integer :: lmax, d, i integer, allocatable :: L(:,:) @@ -3151,25 +3596,9 @@ integer(c_int32_t) function test_qmckl_ao_polynomial_vgl(context) bind(C) test_qmckl_ao_polynomial_vgl = & qmckl_ao_polynomial_vgl(context, X, R, lmax, n, L, ldl, VGL, ldv) - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "polynomial_vgl_1_2"//C_NULL_CHAR, & - DBLE(VGL(1,2)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "polynomial_vgl_2_2"//C_NULL_CHAR, & - DBLE(VGL(2,2)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "polynomial_vgl_3_2"//C_NULL_CHAR, & - DBLE(VGL(3,2)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "polynomial_vgl_4_2"//C_NULL_CHAR, & - DBLE(VGL(4,2)), DBLE(0), DBLE(epsilon)) - - vfc_err = qmckl_probe_check("ao"//C_NULL_CHAR, "polynomial_vgl_5_2"//C_NULL_CHAR, & - DBLE(VGL(5,2)), DBLE(0), DBLE(epsilon)) - if (test_qmckl_ao_polynomial_vgl /= QMCKL_SUCCESS) return if (n /= d) return -#ifndef VFC_CI do j=1,n test_qmckl_ao_polynomial_vgl = QMCKL_FAILURE do i=1,3 @@ -3220,7 +3649,6 @@ integer(c_int32_t) function test_qmckl_ao_polynomial_vgl(context) bind(C) end if if (dabs(1.d0 - VGL(5,j) / w) > epsilon ) return end do -#endif test_qmckl_ao_polynomial_vgl = QMCKL_SUCCESS @@ -3245,7 +3673,10 @@ qmckl_exit_code qmckl_get_ao_vgl(qmckl_context context, double* const ao_vgl); qmckl_exit_code qmckl_get_ao_vgl(qmckl_context context, double* const ao_vgl) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_ao_vgl", + NULL); } qmckl_exit_code rc; @@ -3288,7 +3719,10 @@ qmckl_exit_code qmckl_provide_ao_vgl(qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return QMCKL_NULL_CONTEXT; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_provide_ao_vgl", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -3772,3 +4206,5 @@ assert( fabs(ao_vgl[1][26][224] - (-3.843864637762753e-09)) < 1.e-14 ); # -*- mode: org -*- # vim: syntax=c + + diff --git a/org/qmckl_mo.org b/org/qmckl_mo.org index 8367a6d..03ff1d1 100644 --- a/org/qmckl_mo.org +++ b/org/qmckl_mo.org @@ -78,10 +78,10 @@ int main() { The following arrays are stored in the context: - |---------------+--------------------+------------------------------------| - | ~type~ | | Gaussian (~'G'~) or Slater (~'S'~) | - | ~mo_num~ | | Number of MOs | - | ~coefficient~ | ~[mo_num, ao_num]~ | Orbital coefficients | + + |---------------+--------------------+----------------------| + | ~mo_num~ | | Number of MOs | + | ~coefficient~ | ~[mo_num][ao_num]~ | Orbital coefficients | Computed data: @@ -103,7 +103,6 @@ typedef struct qmckl_mo_basis_struct { int32_t uninitialized; bool provided; - char type; } qmckl_mo_basis_struct; #+end_src @@ -115,33 +114,24 @@ typedef struct qmckl_mo_basis_struct { this mechanism. ** Access functions - - #+begin_src c :comments org :tangle (eval h_private_func) :exports none -char qmckl_get_mo_basis_type (const qmckl_context context); -int64_t qmckl_get_mo_basis_mo_num (const qmckl_context context); -double* qmckl_get_mo_basis_coefficient (const qmckl_context context); + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_mo_basis_mo_num (const qmckl_context context, + int64_t* mo_num); #+end_src - When all the data for the AOs have been provided, the following - function returns ~true~. - - #+begin_src c :comments org :tangle (eval h_func) -bool qmckl_mo_basis_provided (const qmckl_context context); - #+end_src - - #+NAME:post - #+begin_src c :exports none -if ( (ctx->mo_basis.uninitialized & mask) != 0) { - return NULL; -} - #+end_src - - #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none -char qmckl_get_mo_basis_type (const qmckl_context context) { - - if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (char) 0; +qmckl_exit_code +qmckl_get_mo_basis_mo_num (const qmckl_context context, + int64_t* mo_num) +{ + if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_mo_basis_mo_num", + NULL); + return (int64_t) 0; } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -150,16 +140,37 @@ char qmckl_get_mo_basis_type (const qmckl_context context) { int32_t mask = 1; if ( (ctx->mo_basis.uninitialized & mask) != 0) { - return (char) 0; + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_mo_basis_mo_num", + NULL); } - assert (ctx->mo_basis.type != (char) 0); - return ctx->mo_basis.type; + assert (ctx->mo_basis.mo_num > (int64_t) 0); + ,*mo_num = ctx->mo_basis.mo_num; + return QMCKL_SUCCESS; } -int64_t qmckl_get_mo_basis_mo_num (const qmckl_context context) { + #+end_src + + #+begin_src c :comments org :tangle (eval h_func) :exports none +qmckl_exit_code +qmckl_get_mo_basis_coefficient (const qmckl_context context, + double* const coefficient, + const int64_t size_max); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :exports none +qmckl_exit_code +qmckl_get_mo_basis_coefficient (const qmckl_context context, + double* const coefficient, + const int64_t size_max) +{ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { - return (int64_t) 0; + return qmckl_failwith( context, + QMCKL_INVALID_CONTEXT, + "qmckl_get_mo_basis_coefficient", + NULL); } qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; @@ -167,14 +178,43 @@ int64_t qmckl_get_mo_basis_mo_num (const qmckl_context context) { int32_t mask = 1 << 1; - if ( (ctx->mo_basis.uninitialized & mask) != 0) { - return (int64_t) 0; + if ( (ctx->ao_basis.uninitialized & mask) != 0) { + return qmckl_failwith( context, + QMCKL_NOT_PROVIDED, + "qmckl_get_mo_basis_coefficient", + NULL); } - assert (ctx->mo_basis.mo_num > (int64_t) 0); - return ctx->mo_basis.mo_num; -} + if (coefficient == NULL) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_2, + "qmckl_get_mo_basis_coefficient", + "NULL pointer"); + } + if (size_max < ctx->ao_basis.ao_num * ctx->mo_basis.mo_num) { + return qmckl_failwith( context, + QMCKL_INVALID_ARG_3, + "qmckl_get_mo_basis_coefficient", + "Array too small. Expected mo_num * ao_num"); + } + + assert (ctx->mo_basis.coefficient != NULL); + memcpy(coefficient, ctx->mo_basis.coefficient, + ctx->ao_basis.ao_num * ctx->mo_basis.mo_num * sizeof(int64_t)); + + return QMCKL_SUCCESS; +} + #+end_src + + When all the data for the AOs have been provided, the following + function returns ~true~. + + #+begin_src c :comments org :tangle (eval h_func) +bool qmckl_mo_basis_provided (const qmckl_context context); + #+end_src + + #+begin_src c :comments org :tangle (eval c) :exports none bool qmckl_mo_basis_provided(const qmckl_context context) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { @@ -196,12 +236,11 @@ bool qmckl_mo_basis_provided(const qmckl_context context) { called. #+begin_src c :comments org :tangle (eval h_func) -qmckl_exit_code qmckl_set_mo_basis_type (qmckl_context context, const char t); qmckl_exit_code qmckl_set_mo_basis_mo_num (qmckl_context context, const int64_t mo_num); qmckl_exit_code qmckl_set_mo_basis_coefficient (qmckl_context context, const double * coefficient); #+end_src - #+NAME:pre2 + #+NAME:pre #+begin_src c :exports none if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { return QMCKL_NULL_CONTEXT; @@ -210,7 +249,7 @@ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { qmckl_context_struct* const ctx = (qmckl_context_struct* const) context; #+end_src - #+NAME:post2 + #+NAME:post #+begin_src c :exports none ctx->mo_basis.uninitialized &= ~mask; ctx->mo_basis.provided = (ctx->mo_basis.uninitialized == 0); @@ -223,24 +262,8 @@ return QMCKL_SUCCESS; #+end_src #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none -qmckl_exit_code qmckl_set_mo_basis_type(qmckl_context context, const char t) { - <> - - if (t != 'G' && t != 'S') { - return qmckl_failwith( context, - QMCKL_INVALID_ARG_2, - "qmckl_set_mo_basis_type", - NULL); - } - - int32_t mask = 1; - ctx->mo_basis.type = t; - - <> -} - qmckl_exit_code qmckl_set_mo_basis_mo_num(qmckl_context context, const int64_t mo_num) { - <> + <
>
 
   if (mo_num <= 0) {
     return qmckl_failwith( context,
@@ -249,16 +272,16 @@ qmckl_exit_code qmckl_set_mo_basis_mo_num(qmckl_context context, const int64_t m
                            "mo_num <= 0");
   }
 
-  int32_t mask = 1 << 1;
+  int32_t mask = 1 ;
   ctx->mo_basis.mo_num = mo_num;
 
-  <>
+  <>
 }
 
 qmckl_exit_code  qmckl_set_mo_basis_coefficient(qmckl_context context, const double* coefficient) {
-  <>
+  <
>
 
-  int32_t mask = 1 << 2;
+  int32_t mask = 1 << 1;
 
   if (ctx->mo_basis.coefficient != NULL) {
     qmckl_exit_code rc = qmckl_free(context, ctx->mo_basis.coefficient);
@@ -283,7 +306,7 @@ qmckl_exit_code  qmckl_set_mo_basis_coefficient(qmckl_context context, const dou
 
   ctx->mo_basis.coefficient = new_array;
 
-  <>
+  <>
 }
 
    #+end_src
@@ -398,20 +421,13 @@ qmckl_exit_code qmckl_provide_mo_vgl(qmckl_context context)
     }
 
     qmckl_exit_code rc; 
-    if (ctx->mo_basis.type == 'G') {
-      rc = qmckl_compute_mo_basis_gaussian_vgl(context,
-                                               ctx->ao_basis.ao_num,
-                                               ctx->mo_basis.mo_num,
-                                               ctx->electron.num,
-                                               ctx->mo_basis.coefficient,
-                                               ctx->ao_basis.ao_vgl,
-                                               ctx->mo_basis.mo_vgl);
-    } else {
-      return qmckl_failwith( context,
-                             QMCKL_FAILURE,
-                             "compute_mo_basis_vgl",
-                             "Not yet implemented");
-    } 
+    rc = qmckl_compute_mo_basis_vgl(context,
+                                    ctx->ao_basis.ao_num,
+                                    ctx->mo_basis.mo_num,
+                                    ctx->electron.num,
+                                    ctx->mo_basis.coefficient,
+                                    ctx->ao_basis.ao_vgl,
+                                    ctx->mo_basis.mo_vgl);
     if (rc != QMCKL_SUCCESS) {
       return rc;
     }
@@ -425,7 +441,7 @@ qmckl_exit_code qmckl_provide_mo_vgl(qmckl_context context)
     
 *** Compute
    :PROPERTIES:
-   :Name:     qmckl_compute_mo_basis_gaussian_vgl
+   :Name:     qmckl_compute_mo_basis_vgl
    :CRetType: qmckl_exit_code
    :FRetType: qmckl_exit_code
    :END:
@@ -441,7 +457,7 @@ qmckl_exit_code qmckl_provide_mo_vgl(qmckl_context context)
 
     
     #+begin_src f90 :comments org :tangle (eval f) :noweb yes
-integer function qmckl_compute_mo_basis_gaussian_vgl_f(context, &
+integer function qmckl_compute_mo_basis_vgl_f(context, &
      ao_num, mo_num, elec_num, &
      coef_normalized, ao_vgl, mo_vgl) &
      result(info)
@@ -501,13 +517,14 @@ integer function qmckl_compute_mo_basis_gaussian_vgl_f(context, &
   deallocate(ao_vgl_big)
 
 end function qmckl_compute_mo_basis_gaussian_vgl_f
+
     #+end_src
 
-   #+CALL: generate_c_header(table=qmckl_mo_basis_gaussian_vgl_args,rettyp=get_value("CRetType"),fname="qmckl_compute_mo_basis_gaussian_vgl"))
+   #+CALL: generate_c_header(table=qmckl_mo_basis_gaussian_vgl_args,rettyp=get_value("CRetType"),fname="qmckl_compute_mo_basis_vgl"))
 
    #+RESULTS:
    #+begin_src c :tangle (eval h_func) :comments org
-   qmckl_exit_code qmckl_compute_mo_basis_gaussian_vgl (
+   qmckl_exit_code qmckl_compute_mo_basis_vgl (
 	 const qmckl_context context,
 	 const int64_t ao_num,
 	 const int64_t mo_num,
@@ -518,11 +535,11 @@ end function qmckl_compute_mo_basis_gaussian_vgl_f
    #+end_src
 
 
-    #+CALL: generate_c_interface(table=qmckl_mo_basis_gaussian_vgl_args,rettyp=get_value("CRetType"),fname="qmckl_compute_mo_basis_gaussian_vgl"))
+    #+CALL: generate_c_interface(table=qmckl_mo_basis_gaussian_vgl_args,rettyp=get_value("CRetType"),fname="qmckl_compute_mo_basis_vgl"))
 
     #+RESULTS:
     #+begin_src f90 :tangle (eval f) :comments org :exports none
-    integer(c_int32_t) function qmckl_compute_mo_basis_gaussian_vgl &
+    integer(c_int32_t) function qmckl_compute_mo_basis_vgl &
 	(context, ao_num, mo_num, elec_num, coef_normalized, ao_vgl, mo_vgl) &
 	bind(C) result(info)
 
@@ -538,15 +555,13 @@ end function qmckl_compute_mo_basis_gaussian_vgl_f
       real    (c_double ) , intent(in)          :: ao_vgl(ao_num,elec_num,5)
       real    (c_double ) , intent(out)         :: mo_vgl(mo_num,elec_num,5)
 
-      integer(c_int32_t), external :: qmckl_compute_mo_basis_gaussian_vgl_f
-      info = qmckl_compute_mo_basis_gaussian_vgl_f &
+      integer(c_int32_t), external :: qmckl_compute_mo_basis_vgl_f
+      info = qmckl_compute_mo_basis_vgl_f &
 	     (context, ao_num, mo_num, elec_num, coef_normalized, ao_vgl, mo_vgl)
 
-    end function qmckl_compute_mo_basis_gaussian_vgl
+    end function qmckl_compute_mo_basis_vgl
     #+end_src
 
-
-    
 *** Test
 
     #+begin_src python :results output :exports none
@@ -724,9 +739,6 @@ rc = qmckl_get_ao_vgl(context, &(ao_vgl[0][0][0][0]));
 assert (rc == QMCKL_SUCCESS);
 
 /* Set up MO data */
-rc = qmckl_set_mo_basis_type(context, typ);
-assert (rc == QMCKL_SUCCESS);
-
 const int64_t mo_num = chbrclf_mo_num;
 rc = qmckl_set_mo_basis_mo_num(context, mo_num);
 assert (rc == QMCKL_SUCCESS);
diff --git a/org/qmckl_tests.org b/org/qmckl_tests.org
index 4d04385..461772e 100644
--- a/org/qmckl_tests.org
+++ b/org/qmckl_tests.org
@@ -60058,8 +60058,8 @@ double chbrclf_elec_coord[chbrclf_walk_num][chbrclf_elec_num][3] = { {
 #+BEGIN_example
   2
 N2
- N         0.000000    0.000000    0.000000
- N         0.000000    0.000000    2.059801
+ N         0.000000    0.000000    0.00
+ N         0.000000    0.000000    1.09
 #+END_example
 
  Nuclear coordinates are stored in atomic units in transposed format.
diff --git a/org/qmckl_trexio.org b/org/qmckl_trexio.org
new file mode 100644
index 0000000..9662938
--- /dev/null
+++ b/org/qmckl_trexio.org
@@ -0,0 +1,1101 @@
+#+TITLE: TREXIO I/O library
+#+SETUPFILE: ../tools/theme.setup
+#+INCLUDE: ../tools/lib.org
+
+The [[https://github.com/trex-coe/trexio][TREXIO library]] enables easy and efficient input/output of wave
+function parameters. In this section we provide high-level functions
+to prepare the context by reading the required data from a TREXIO file.
+
+* Headers                                                          :noexport:
+  #+begin_src elisp :noexport :results none
+(org-babel-lob-ingest "../tools/lib.org")
+#+end_src
+
+
+  #+begin_src c :tangle (eval c_test) :noweb yes
+#include "qmckl.h"
+#include 
+#include 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "chbrclf.h"
+#include 
+#include 
+#include 
+
+int main() {
+  qmckl_context context;
+  context = qmckl_context_create();
+#ifdef HAVE_TREXIO
+  #+end_src
+
+  #+begin_src c :tangle (eval c)
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDINT_H
+#include 
+#elif HAVE_INTTYPES_H
+#include 
+#endif
+
+#ifdef HAVE_TREXIO
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "qmckl.h"
+#include "qmckl_memory_private_type.h"
+#include "qmckl_memory_private_func.h"
+  #+end_src
+
+* Local functions
+
+  Functions defined in this section are all local: they should not be
+  exposed in the API. To identify them, we append ~_X~ to
+  their name.
+
+  Users are not able to call directly these functions, so by
+  construction the context can't be ~NULL~, hence we can check this
+  with an ~assert~ statement.
+
+  In the functions defined in this section, we use as local variables
+  - ~rc~: the return code for QMCkl functions
+  - ~rcio~: the return code for TREXIO functions.
+
+** Open file
+
+   We first define a helper function to open a file by first trying to
+   use the TEXT back end, and then the HDF5 back end. If both
+   strategies fail, a ~NULL~ pointer is returned. This will allow to
+   open only once the file and call multiple small functions to read
+   groups of data by passing the ~trexio_t~ handle.
+
+   #+begin_src c :tangle (eval c)
+#ifdef HAVE_TREXIO
+trexio_t* qmckl_trexio_open_X(const char* file_name, qmckl_exit_code* rc)
+{
+  *rc = QMCKL_SUCCESS;
+  trexio_t* file = NULL;
+
+  file = trexio_open(file_name, 'r', TREXIO_TEXT, rc);
+  if (file != NULL) return file;
+
+  file = trexio_open(file_name, 'r', TREXIO_HDF5, rc);
+  if (file != NULL) return file;
+
+  *rc = QMCKL_FAILURE;
+  return NULL;
+}
+#endif
+   #+end_src
+
+** Electron
+
+   In this section we read all the data into the electron data structure.
+   We read the number of up-spin and down-spin electrons.
+
+   #+begin_src c :tangle (eval c)
+#ifdef HAVE_TREXIO
+qmckl_exit_code
+qmckl_trexio_read_electron_X(qmckl_context context, trexio_t* const file)
+{
+  assert (context != (qmckl_context) 0);
+  assert (file != NULL);
+
+  int rcio = 0;
+
+  int64_t up_num = 0L;
+  int64_t dn_num = 0L;
+
+  rcio = trexio_read_electron_up_num_64(file, &up_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_electron_up_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (up_num >= 0L);
+
+  rcio = trexio_read_electron_dn_num_64(file, &dn_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_electron_dn_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (dn_num >= 0L);
+
+
+  qmckl_exit_code rc;
+  rc = qmckl_set_electron_num(context, up_num, dn_num);
+  return rc;
+}
+#endif
+   #+end_src
+
+** Nucleus
+
+   In this section we read the number of nuclei, the molecular geometry and nuclear charges.
+
+   #+begin_src c :tangle (eval c)
+#ifdef HAVE_TREXIO
+qmckl_exit_code
+qmckl_trexio_read_nucleus_X(qmckl_context context, trexio_t* const file)
+{
+  assert (context != (qmckl_context) 0);
+  assert (file != NULL);
+
+  qmckl_exit_code rc;
+  int rcio = 0;
+   #+end_src
+
+*** Number of nuclei
+
+   #+begin_src c :tangle (eval c)
+  int64_t nucleus_num = 0L;
+
+  rcio = trexio_read_nucleus_num_64(file, &nucleus_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_nucleus_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (nucleus_num > 0);
+  rc = qmckl_set_nucleus_num(context, nucleus_num);
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+   #+end_src
+
+*** Nuclear charges
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = nucleus_num * sizeof(double);
+
+    double* nucl_charge = (double*) qmckl_malloc(context, mem_info);
+
+    if (nucl_charge == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_nucleus_X",
+                             NULL);
+    }
+
+    assert (nucl_charge != NULL);
+
+    rcio = trexio_read_nucleus_charge_64(file, nucl_charge);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_nucleus_charge",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_nucleus_charge(context, nucl_charge);
+
+    qmckl_free(context, nucl_charge);
+    nucl_charge = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+
+  }
+   #+end_src
+
+*** Nuclear coordinates
+
+    Now, we read the molecular geometry. It is stored in normal format
+    in the TREXIO file (~'N'~), so it will be automatically transposed internally.
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = nucleus_num * 3 * sizeof(double);
+
+    double* nucl_coord = (double*) qmckl_malloc(context, mem_info);
+
+    if (nucl_coord == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_nucleus_X",
+                             NULL);
+    }
+
+    assert (nucl_coord != NULL);
+
+    rcio = trexio_read_nucleus_coord_64(file, nucl_coord);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_nucleus_charge",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_nucleus_coord(context, 'N', nucl_coord);
+
+    qmckl_free(context, nucl_coord);
+    nucl_coord = NULL;
+
+    if (rc != QMCKL_SUCCESS) {
+      return rc;
+    }
+  }
+   #+end_src
+
+
+   #+begin_src c :tangle (eval c)
+
+  return QMCKL_SUCCESS;
+}
+#endif
+   #+end_src
+
+** Basis set and AOs
+
+   In this section we read the atomic basis set and atomic orbitals.
+
+   #+begin_src c :tangle (eval c)
+#ifdef HAVE_TREXIO
+qmckl_exit_code
+qmckl_trexio_read_ao_X(qmckl_context context, trexio_t* const file)
+{
+  assert (context != (qmckl_context) 0);
+  assert (file != NULL);
+
+  qmckl_exit_code rc;
+  int rcio = 0;
+  int64_t nucleus_num = 0L;
+
+  rc = qmckl_get_nucleus_num(context, &nucleus_num);
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Basis set type
+
+   #+begin_src c :tangle (eval c)
+#define MAX_STR_LEN 1024
+  char basis_type[MAX_STR_LEN];
+
+  rcio = trexio_read_basis_type(file, basis_type, MAX_STR_LEN);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_basis_type",
+                           trexio_string_of_error(rcio));
+  }
+
+  if (basis_type[0] == 'G') {
+    rc = qmckl_set_ao_basis_type(context, basis_type[0]);
+  } else {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_basis_type",
+                           "Invalid basis type");
+  }
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Number of shells
+
+   #+begin_src c :tangle (eval c)
+  int64_t shell_num = 0L;
+
+  rcio = trexio_read_basis_num_64(file, &shell_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_basis_shell_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (shell_num > 0);
+  rc = qmckl_set_ao_basis_shell_num(context, shell_num);
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Number of primitives
+
+   #+begin_src c :tangle (eval c)
+  int64_t prim_num = 0L;
+
+  rcio = trexio_read_basis_prim_num_64(file, &prim_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_basis_prim_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (prim_num > 0);
+  rc = qmckl_set_ao_basis_prim_num(context, prim_num);
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Number of atomic orbitals
+
+   #+begin_src c :tangle (eval c)
+  int64_t ao_num = 0LL;
+
+  rcio = trexio_read_ao_num_64(file, &ao_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_ao_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (ao_num > 0);
+  rc = qmckl_set_ao_basis_ao_num(context, ao_num);
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Nucleus_index array
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = nucleus_num * sizeof(int64_t);
+
+    int64_t* nucleus_index = (int64_t*) qmckl_malloc(context, mem_info);
+
+    if (nucleus_index == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_nucleus_index_X",
+                             NULL);
+    }
+
+    assert (nucleus_index != NULL);
+
+    rcio = trexio_read_basis_nucleus_index_64(file, nucleus_index);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_nucleus_index",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_nucleus_index(context, nucleus_index);
+
+    qmckl_free(context, nucleus_index);
+    nucleus_index = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Number of shells per nucleus
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = nucleus_num * sizeof(int64_t);
+
+    int64_t* nucleus_shell_num = (int64_t*) qmckl_malloc(context, mem_info);
+
+    if (nucleus_shell_num == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_nucleus_shell_num_X",
+                             NULL);
+    }
+
+    assert (nucleus_shell_num != NULL);
+
+    rcio = trexio_read_basis_nucleus_shell_num_64(file, nucleus_shell_num);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_nucleus_shell_num",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_nucleus_shell_num(context, nucleus_shell_num);
+
+    qmckl_free(context, nucleus_shell_num);
+    nucleus_shell_num = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Angular momentum
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = shell_num * sizeof(int32_t);
+
+    int32_t* shell_ang_mom = (int32_t*) qmckl_malloc(context, mem_info);
+
+    if (shell_ang_mom == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_shell_ang_mom_X",
+                             NULL);
+    }
+
+    assert (shell_ang_mom != NULL);
+
+    rcio = trexio_read_basis_shell_ang_mom_32(file, shell_ang_mom);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_shell_ang_mom",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_shell_ang_mom(context, shell_ang_mom);
+
+    qmckl_free(context, shell_ang_mom);
+    shell_ang_mom = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Number of primitives per shell
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = shell_num * sizeof(int64_t);
+
+    int64_t* shell_prim_num = (int64_t*) qmckl_malloc(context, mem_info);
+
+    if (shell_prim_num == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_shell_prim_num_X",
+                             NULL);
+    }
+
+    assert (shell_prim_num != NULL);
+
+    rcio = trexio_read_basis_shell_prim_num_64(file, shell_prim_num);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_shell_prim_num",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_shell_prim_num(context, shell_prim_num);
+
+    qmckl_free(context, shell_prim_num);
+    shell_prim_num = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Indices of the primitives
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = shell_num * sizeof(int64_t);
+
+    int64_t* shell_prim_index = (int64_t*) qmckl_malloc(context, mem_info);
+
+    if (shell_prim_index == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_shell_prim_index_X",
+                             NULL);
+    }
+
+    assert (shell_prim_index != NULL);
+
+    rcio = trexio_read_basis_shell_prim_index_64(file, shell_prim_index);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_shell_prim_index",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_shell_prim_index(context, shell_prim_index);
+
+    qmckl_free(context, shell_prim_index);
+    shell_prim_index = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Normalization of the shells
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = shell_num * sizeof(double);
+
+    double* shell_factor = (double*) qmckl_malloc(context, mem_info);
+
+    if (shell_factor == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_shell_factor_X",
+                             NULL);
+    }
+
+    assert (shell_factor != NULL);
+
+    rcio = trexio_read_basis_shell_factor_64(file, shell_factor);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_shell_factor",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_shell_factor(context, shell_factor);
+
+    qmckl_free(context, shell_factor);
+    shell_factor = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Exponents
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = prim_num * sizeof(double);
+
+    double* exponent = (double*) qmckl_malloc(context, mem_info);
+
+    if (exponent == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_exponent_X",
+                             NULL);
+    }
+
+    assert (exponent != NULL);
+
+    rcio = trexio_read_basis_exponent_64(file, exponent);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_exponent",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_exponent(context, exponent);
+
+    qmckl_free(context, exponent);
+    exponent = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Coefficients
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = prim_num * sizeof(double);
+
+    double* coefficient = (double*) qmckl_malloc(context, mem_info);
+
+    if (coefficient == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_coefficient_X",
+                             NULL);
+    }
+
+    assert (coefficient != NULL);
+
+    rcio = trexio_read_basis_coefficient_64(file, coefficient);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_coefficient",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_coefficient(context, coefficient);
+
+    qmckl_free(context, coefficient);
+    coefficient = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+*** Normalization of the primitivies
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = prim_num * sizeof(double);
+
+    double* prim_factor = (double*) qmckl_malloc(context, mem_info);
+
+    if (prim_factor == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_basis_prim_factor_X",
+                             NULL);
+    }
+
+    assert (prim_factor != NULL);
+
+    rcio = trexio_read_basis_prim_factor_64(file, prim_factor);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_basis_prim_factor",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_ao_basis_prim_factor(context, prim_factor);
+
+    qmckl_free(context, prim_factor);
+    prim_factor = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+  }
+   #+end_src
+
+
+   #+begin_src c :tangle (eval c)
+
+  return QMCKL_SUCCESS;
+}
+#endif
+   #+end_src
+
+** Molecular orbitals
+
+   In this section we read the MO coefficients.
+
+   #+begin_src c :tangle (eval c)
+#ifdef HAVE_TREXIO
+qmckl_exit_code
+qmckl_trexio_read_mo_X(qmckl_context context, trexio_t* const file)
+{
+  assert (context != (qmckl_context) 0);
+  assert (file != NULL);
+
+  qmckl_exit_code rc;
+  int rcio = 0;
+  int64_t ao_num = 0L;
+
+  rc = qmckl_get_ao_basis_ao_num(context, &ao_num);
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+
+   #+end_src
+
+*** Number of MOs
+
+   #+begin_src c :tangle (eval c)
+  int64_t mo_num = 0L;
+
+  rcio = trexio_read_mo_num_64(file, &mo_num);
+  if (rcio != TREXIO_SUCCESS) {
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "trexio_read_mo_num",
+                           trexio_string_of_error(rcio));
+  }
+
+  assert (mo_num > 0);
+  rc = qmckl_set_mo_basis_mo_num(context, mo_num);
+
+  if (rc != QMCKL_SUCCESS)
+    return rc;
+   #+end_src
+
+*** MO coefficients
+
+   #+begin_src c :tangle (eval c)
+  {
+    qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
+    mem_info.size = ao_num * mo_num * sizeof(double);
+
+    double* mo_coef = (double*) qmckl_malloc(context, mem_info);
+
+    if (mo_coef == NULL) {
+      return qmckl_failwith( context,
+                             QMCKL_ALLOCATION_FAILED,
+                             "qmckl_trexio_read_mo_X",
+                             NULL);
+    }
+
+    assert (mo_coef != NULL);
+
+    rcio = trexio_read_mo_coefficient_64(file, mo_coef);
+    if (rcio != TREXIO_SUCCESS) {
+      return qmckl_failwith( context,
+                             QMCKL_FAILURE,
+                             "trexio_read_mo_coefficient",
+                             trexio_string_of_error(rcio));
+    }
+
+    rc = qmckl_set_mo_basis_coefficient(context, mo_coef);
+
+    qmckl_free(context, mo_coef);
+    mo_coef = NULL;
+
+    if (rc != QMCKL_SUCCESS)
+      return rc;
+
+  }
+   #+end_src
+
+   #+begin_src c :tangle (eval c)
+
+  return QMCKL_SUCCESS;
+}
+#endif
+   #+end_src
+
+** TODO ECP
+* Read everything
+
+  #+begin_src c :tangle (eval h_func)
+qmckl_exit_code qmckl_trexio_read(const qmckl_context context, const char* file_name);
+  #+end_src
+
+  #+begin_src c :tangle (eval c)
+qmckl_exit_code
+qmckl_trexio_read(const qmckl_context context, const char* file_name)
+{
+  if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
+    return false;
+  }
+
+  qmckl_exit_code rc;
+
+#ifdef HAVE_TREXIO
+  trexio_t* file = qmckl_trexio_open_X(file_name, &rc);
+  if (file == NULL) {
+    trexio_close(file);
+    return qmckl_failwith( context,
+                           QMCKL_INVALID_ARG_2,
+                           "qmckl_trexio_read",
+                           trexio_string_of_error(rc));
+  }
+
+  assert (file != NULL);
+
+  rc = qmckl_trexio_read_electron_X(context, file);
+  if (rc != QMCKL_SUCCESS) {
+    trexio_close(file);
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "qmckl_trexio_read",
+                           "Error reading electron");
+  }
+
+  rc = qmckl_trexio_read_nucleus_X(context, file);
+  if (rc != QMCKL_SUCCESS) {
+    trexio_close(file);
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "qmckl_trexio_read",
+                           "Error reading nucleus");
+  }
+
+  rc = qmckl_trexio_read_ao_X(context, file);
+  if (rc != QMCKL_SUCCESS) {
+    trexio_close(file);
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "qmckl_trexio_read",
+                           "Error reading AOs");
+  }
+
+  rc = qmckl_trexio_read_mo_X(context, file);
+  if (rc != QMCKL_SUCCESS) {
+    trexio_close(file);
+    return qmckl_failwith( context,
+                           QMCKL_FAILURE,
+                           "qmckl_trexio_read",
+                           "Error reading MOs");
+  }
+
+  trexio_close(file);
+  file = NULL;
+#else
+
+  rc = qmckl_failwith( context,
+                       QMCKL_FAILURE,
+                       "qmckl_trexio_read",
+                       "QMCkl was not compiled without TREXIO");
+#endif
+  return rc;
+}
+  #+end_src
+
+* Test
+
+  #+begin_src c :tangle (eval c_test)
+#ifdef HAVE_TREXIO
+
+qmckl_exit_code rc;
+char fname[256];
+char message[256];
+
+#ifndef QMCKL_TEST_DIR
+#error "QMCKL_TEST_DIR is not defined"
+#endif
+
+strncpy(fname, QMCKL_TEST_DIR,255);
+strncat(fname, "/chbrclf", 255);
+printf("Test file: %s\n", fname);
+rc = qmckl_trexio_read(context, fname);
+
+if (rc != QMCKL_SUCCESS) {
+  printf("%s\n", qmckl_string_of_error(rc));
+  qmckl_get_error(context, &rc, fname, message);
+  printf("%s\n", fname);
+  printf("%s\n", message);
+ }
+
+assert ( rc == QMCKL_SUCCESS );
+
+  #+end_src
+
+*** Electrons
+
+  #+begin_src c :tangle (eval c_test)
+printf("Electrons\n");
+int64_t up_num, dn_num;
+rc = qmckl_get_electron_up_num(context, &up_num);
+assert (rc == QMCKL_SUCCESS);
+assert (up_num == chbrclf_elec_up_num);
+
+rc = qmckl_get_electron_down_num(context, &dn_num);
+assert (rc == QMCKL_SUCCESS);
+assert (dn_num == chbrclf_elec_dn_num);
+
+  #+end_src
+
+*** Nuclei
+
+  #+begin_src c :tangle (eval c_test)
+printf("Nuclei\n");
+
+int64_t nucl_num;
+rc = qmckl_get_nucleus_num(context, &nucl_num);
+assert (rc == QMCKL_SUCCESS);
+assert (nucl_num == chbrclf_nucl_num);
+
+printf("Nuclear charges\n");
+double * charge = (double*) malloc (nucl_num * sizeof(double));
+rc = qmckl_get_nucleus_charge(context, charge);
+assert (rc == QMCKL_SUCCESS);
+for (int i=0 ; i