Skip to content
Permalink
Browse files

Merge pull request #127 from pseewald/fortran

Fortran interface: fix dimensions of 3-center ERI function pointer arrays
  • Loading branch information...
evaleev committed May 14, 2019
2 parents 95b8dfb + 172d13f commit 5458ab2fb2fd51dcd19f1e8122a451f2a0808074
Showing with 43 additions and 9 deletions.
  1. +3 −0 CHANGES
  2. +1 −1 bin/travisci_build_linux.sh
  3. +9 −2 doc/progman/progman.tex
  4. +30 −6 export/fortran/libint_f.F90
@@ -3,6 +3,9 @@

Following is a brief summary of changes made in each release of Libint.

- 2019-xx-yy: 2.6.0-beta.2
- resolved issue #127: incorrect dimensions of 3-center ERI function pointer array used by Fortran interface

- 2019-05-07: 2.6.0-beta.1
- can read PBC-extended XYZ files
- provided (pkg-config based) FindLibint2.cmake module for CMake projects
@@ -63,7 +63,7 @@ cmake_minimum_required(VERSION 3.8)
find_package(Libint2 2.6.0 MODULE QUIET REQUIRED)
find_package(Threads) # for some reason clang does not link in threading support even though we are using C++ threads
add_executable(hf++ EXCLUDE_FROM_ALL ../tests/hartree-fock/hartree-fock++.cc)
target_link_libraries(hf++ Libint2::LibintCXX ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(hf++ Libint2::LibintCXX \${CMAKE_THREAD_LIBS_INIT})
EOF
cmake . -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/libint2/lib/cmake/libint2
cmake --build . --target hf++
@@ -653,6 +653,10 @@ \subsection{Modern Fortran}
The definition of the Fortran derived type {\tt Libint\_t} is shown in Listing \ref{lst:libinttf}.
The only notable difference to the corresponding C struct (Listing \ref{lst:libintt}) is that variable names starting with an underscore in C are prefixed with a letter {\tt f} in Fortran.
Refer to Listing \ref{lst:apif} for Fortran prototypes of procedures and data.
Note that the index order of multidimensional arrays is reverse in fortran
compared to C due to row-major vs. column-major order such that e.g. {\tt
libint2\_build\_eri[am1][am2][am3][am4]} in C corresponds to {\tt
libint2\_build\_eri(am4, am3, am2, am1)} in Fortran.

\begin{lstlisting}[label=lst:libinttf,caption=Fortran definition of the \LIBINT\ integral evaluator type.]{}
type, bind(c) :: Libint_t
@@ -661,7 +665,7 @@ \subsection{Modern Fortran}
real(LIBINT2_REALTYPE), dimension(VECLEN) :: f_aB_s___0___ElecPot_s___0___Ab__up_2
real(LIBINT2_REALTYPE), dimension(VECLEN) :: f_aB_s___0___ElecPot_s___0___Ab__up_3
real(LIBINT2_REALTYPE), dimension(VECLEN) :: f_aB_s___0___ElecPot_s___0___Ab__up_4
! and so on until 4 * LIBINT2_MAX_AM_ERI
! and so on until 4 * LIBINT2_MAX_AM_eri

real(LIBINT2_REALTYPE), dimension(VECLEN) :: WP_x, WP_y, WP_z
real(LIBINT2_REALTYPE), dimension(VECLEN) :: WQ_x, WQ_y, WQ_z
@@ -721,7 +725,9 @@ \subsection{Modern Fortran}
Fortran pointers are not directly interoperable with C pointers, therefore special datatypes for C pointers ({\tt c\_ptr} and {\tt c\_funptr}) and methods
from {\tt iso\_c\_binding} to convert to Fortran pointers ({\tt c\_f\_pointer} and {\tt c\_f\_procpointer}) are needed.
If your code should be compatible with different configurations of libint compiler, you need to use conditional compilation based on the macros provided
in {\tt libint2/config.h} (such as macro {\tt LIBINT\_CONTRACTED\_INTS}, see listing \ref{lst:usefortran}).
in {\tt libint2/config.h} and {\tt libint2/libint2\_params.h} such as the
macros {\tt LIBINT2\_MAX\_AM\_eri} and {\tt LIBINT\_CONTRACTED\_INTS} (for
their use see listings \ref{lst:libinttf} and \ref{lst:usefortran}).

An example subroutine that demonstrates how to actually calculate integrals using \LIBINT\ is provided in Listing \ref{lst:usefortran}.
This example is a translation of Listing \ref{lst:usecpp} to Fortran and evaluates four-center two-body Coulomb integrals over primitive Gaussians.
@@ -730,6 +736,7 @@ \subsection{Modern Fortran}
\begin{lstlisting}[label=lst:usefortran, caption=Using \LIBINT\ from Fortran.]{}
! include libint configuration-specific macros (may not be needed)
#include <libint2/config.h>
#include <libint2/libint2_params.h>

module libint_f_example

@@ -10,6 +10,21 @@ MODULE libint_f
#ifdef LIBINT2_MAX_AM
INTEGER, PARAMETER :: libint2_max_am = LIBINT2_MAX_AM
#endif
#ifdef LIBINT2_MAX_AM_default
INTEGER, PARAMETER :: libint2_max_am_default = LIBINT2_MAX_AM_default
#else
# error "LIBINT2_MAX_AM_default is expected to be defined, libint2_params.h is misgenerated"
#endif
#ifdef LIBINT2_MAX_AM_default1
INTEGER, PARAMETER :: libint2_max_am_default1 = LIBINT2_MAX_AM_default1
#else
INTEGER, PARAMETER :: libint2_max_am_default1 = LIBINT2_MAX_AM_default
#endif
#ifdef LIBINT2_MAX_AM_default2
INTEGER, PARAMETER :: libint2_max_am_default2 = LIBINT2_MAX_AM_default2
#else
INTEGER, PARAMETER :: libint2_max_am_default2 = LIBINT2_MAX_AM_default
#endif
#ifdef LIBINT2_MAX_AM_eri
INTEGER, PARAMETER :: libint2_max_am_eri = LIBINT2_MAX_AM_eri
#endif
@@ -28,6 +43,15 @@ MODULE libint_f
#ifdef LIBINT2_MAX_AM_3eri2
INTEGER, PARAMETER :: libint2_max_am_3eri2 = LIBINT2_MAX_AM_3eri2
#endif
#ifdef LIBINT2_MAX_AM_2eri
INTEGER, PARAMETER :: libint2_max_am_2eri = LIBINT2_MAX_AM_2eri
#endif
#ifdef LIBINT2_MAX_AM_2eri1
INTEGER, PARAMETER :: libint2_max_am_2eri1 = LIBINT2_MAX_AM_2eri1
#endif
#ifdef LIBINT2_MAX_AM_2eri2
INTEGER, PARAMETER :: libint2_max_am_2eri2 = LIBINT2_MAX_AM_2eri2
#endif

INTEGER, PARAMETER :: libint2_max_veclen = LIBINT2_MAX_VECLEN

@@ -47,27 +71,27 @@ MODULE libint_f
#endif

#ifdef INCLUDE_ERI2
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_eri, 0:libint2_max_am_eri), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_2eri, 0:libint2_max_am_2eri), &
BIND(C) :: libint2_build_2eri
#if INCLUDE_ERI2 >= 1
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_eri1, 0:libint2_max_am_eri1), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_2eri1, 0:libint2_max_am_2eri1), &
BIND(C) :: libint2_build_2eri1
#endif
#if INCLUDE_ERI2 >= 2
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_eri2, 0:libint2_max_am_eri2), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_2eri2, 0:libint2_max_am_2eri2), &
BIND(C) :: libint2_build_2eri2
#endif
#endif

#ifdef INCLUDE_ERI3
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_3eri, 0:libint2_max_am, 0:libint2_max_am), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_default, 0:libint2_max_am_default, 0:libint2_max_am_3eri), &
BIND(C) :: libint2_build_3eri
#if INCLUDE_ERI3 >= 1
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_3eri1, 0:libint2_max_am, 0:libint2_max_am), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_default1, 0:libint2_max_am_default1, 0:libint2_max_am_3eri1), &
BIND(C) :: libint2_build_3eri1
#endif
#if INCLUDE_ERI3 >= 2
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_3eri2, 0:libint2_max_am, 0:libint2_max_am), &
TYPE(C_FUNPTR), DIMENSION(0:libint2_max_am_default2, 0:libint2_max_am_default2, 0:libint2_max_am_3eri2), &
BIND(C) :: libint2_build_3eri2
#endif
#endif

0 comments on commit 5458ab2

Please sign in to comment.
You can’t perform that action at this time.