diff --git a/README.html b/README.html index e4506cd..f5bd035 100644 --- a/README.html +++ b/README.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + QMCkl source code documentation @@ -241,7 +241,9 @@ org_html_manager.setup(); // activate after the parameters are set
  • Slater Determinant
  • Sherman-Morrison-Woodbury
  • CHAMP Jastrow Factor
  • +
  • CHAMP Jastrow Factor Single
  • Local Energy
  • +
  • Forces
  • TREXIO I/O library
  • Data for Tests
  • Verificarlo CI
  • @@ -277,7 +279,7 @@ and bug reports should be submitted at

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl.html b/qmckl.html index f78ff7a..02e55bf 100644 --- a/qmckl.html +++ b/qmckl.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Introduction @@ -258,36 +258,36 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Installing QMCkl

    +
    +

    1. Installing QMCkl

    The latest version fo QMCkl can be downloaded @@ -296,8 +296,8 @@ The latest version fo QMCkl can be downloaded

    -
    -

    1.1. Installing from the released tarball (for end users)

    +
    +

    1.1. Installing from the released tarball (for end users)

    QMCkl is built with GNU Autotools, so the usual @@ -312,8 +312,8 @@ options are defined using CFLAGS and FCFLAGS.

    -
    -

    1.2. Installing from the source repository (for developers)

    +
    +

    1.2. Installing from the source repository (for developers)

    To compile from the source repository, additional dependencies are @@ -334,8 +334,8 @@ to be executed first.

    -
    -

    2. Using QMCkl

    +
    +

    2. Using QMCkl

    The qmckl.h header file installed in the ${prefix}/include directory @@ -364,12 +364,12 @@ Both files are located in the include/ directory.

    -
    -

    3. Developing in QMCkl

    +
    +

    3. Developing in QMCkl

    -
    -

    3.1. Literate programming

    +
    +

    3.1. Literate programming

    In a traditional source code, most of the lines of source files of a program @@ -419,8 +419,8 @@ tarball contains the generated source code.

    -
    -

    3.2. Source code editing

    +
    +

    3.2. Source code editing

    For a tutorial on literate programming with org-mode, follow this link. @@ -451,8 +451,8 @@ org-mode.

    -
    -

    3.3. Choice of the programming language

    +
    +

    3.3. Choice of the programming language

    Most of the codes of the TREX CoE are written in Fortran with some @@ -496,7 +496,7 @@ call directly the Fortran routines, but call instead the C binding function and an iso_c_binding is still required:

    -
    +
              ISO_C_BINDING        ISO_C_BINDING
     Fortran --------------->  C  --------------->  Fortran
     
    @@ -516,8 +516,8 @@ For more guidelines on using Fortran to generate a C interface, see
    -
    -

    3.4. Coding rules

    +
    +

    3.4. Coding rules

    The authors should follow the recommendations of the C99 @@ -537,8 +537,8 @@ make cppcheck ; cat cppcheck.out

    -
    -

    3.5. Design of the library

    +
    +

    3.5. Design of the library

    The proposed API should allow the library to: deal with memory transfers @@ -549,8 +549,8 @@ functions (see below).

    -
    -

    3.6. Naming conventions

    +
    +

    3.6. Naming conventions

    To avoid namespace collisions, we use qmckl_ as a prefix for all exported @@ -571,8 +571,8 @@ form is allowed.

    -
    -

    3.7. Application programming interface

    +
    +

    3.7. Application programming interface

    In the C language, the number of bits used by the integer types can change @@ -604,15 +604,15 @@ bindings in other languages in other repositories.

    -
    -

    3.8. Global state

    +
    +

    3.8. Global state

    Global variables should be avoided in the library, because it is possible that one single program needs to use multiple instances of the library. To solve this problem we propose to use a pointer to a context variable, built by the library with the -qmckl_context_create function. The context contains the global +qmckl_context_create function. The context contains the global state of the library, and is used as the first argument of many QMCkl functions.

    @@ -626,8 +626,8 @@ the state is done by setters and getters, prefixed by
    -
    -

    3.9. Headers

    +
    +

    3.9. Headers

    A single qmckl.h header to be distributed by the library @@ -715,8 +715,8 @@ and the types definitions should be written in the *fh_type.f90 fil

    -
    -

    3.10. Low-level functions

    +
    +

    3.10. Low-level functions

    Low-level functions are very simple functions which are leaves of @@ -725,14 +725,14 @@ the function call tree (they don't call any other QMCkl function).

    These functions are pure, and unaware of the QMCkl -context. They are not allowed to allocate/deallocate memory, and +context. They are not allowed to allocate/deallocate memory, and if they need temporary memory it should be provided in input.

    -
    -

    3.11. High-level functions

    +
    +

    3.11. High-level functions

    High-level functions are at the top of the function call tree. @@ -744,8 +744,8 @@ temporary storage, to simplify the use of accelerators.

    -
    -

    3.12. Numerical precision

    +
    +

    3.12. Numerical precision

    The minimal number of bits of precision required for a function @@ -753,7 +753,7 @@ should be given as an input of low-level computational functions. This input will be used to define the values of the different thresholds that might be used to avoid computing unnecessary noise. High-level functions will use the precision -specified in the context variable. +specified in the context variable.

    @@ -821,8 +821,8 @@ following points :

    -
    -

    3.13. Algorithms

    +
    +

    3.13. Algorithms

    Reducing the scaling of an algorithm usually implies also reducing @@ -838,7 +838,7 @@ implemented adapted to different problem sizes.

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_ao.html b/qmckl_ao.html index 711ebf8..ce70cb5 100644 --- a/qmckl_ao.html +++ b/qmckl_ao.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Atomic Orbitals @@ -258,62 +258,75 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Introduction

    +
    +

    1. Introduction

    The atomic basis set is defined as a list of shells. Each shell \(s\) is @@ -376,19 +389,19 @@ gradients and Laplacian of the atomic basis functions.

    -
    -

    2. Context

    +
    +

    2. Context

    -
    -

    2.1. Constant data

    +
    +

    2.1. Constant data

    The following arrays are stored in the context, and need to be set when initializing the library:

    - +
    @@ -562,7 +575,7 @@ The following data is computed when the basis is finalized: For H2 with the following basis set,

    -
    +
     HYDROGEN
     S   5
       1         3.387000E+01           6.068000E-03
    @@ -586,7 +599,7 @@ D   1
     we have:
     

    -
    +
     type = 'G'
     shell_num = 12
     prim_num = 20
    @@ -622,7 +635,7 @@ calling the functions:
     

    -
    qmckl_exit_code qmckl_set_ao_basis_$V$ ( qmckl_context context,
    +
    qmckl_exit_code qmckl_set_ao_basis_$V$ ( qmckl_context context,
                                              const $type_of_V$ $V$);
     
     qmckl_exit_code qmckl_get_ao_basis_$V$ ( const qmckl_context context,
    @@ -659,7 +672,7 @@ For array variables, use the rule:
     

    -
    qmckl_exit_code qmckl_set_ao_basis_$V$ ( qmckl_context context,
    +
    qmckl_exit_code qmckl_set_ao_basis_$V$ ( qmckl_context context,
                                              const $type_of_V$ $V$,
                                              const int64_t size_max);
     
    @@ -697,17 +710,17 @@ For array variables, use the rule:
     
    -
    -

    2.1.1. Initialization functions

    +
    +

    2.1.1. Initialization functions

    size_max is the dimension of the input array, which should be -equal of larger than the value given in the table of section 2. +equal of larger than the value given in the table of section 2.

    -
    -
    2.1.1.1. C interface
    +
    +
    2.1.1.1. C interface

    To set the basis set, all the following functions need to be @@ -831,8 +844,8 @@ called.

    -
    -
    2.1.1.2. Fortran interface
    +
    +
    2.1.1.2. Fortran interface
    interface
    @@ -1015,17 +1028,17 @@ called.
     
    -
    -

    2.1.2. Access functions

    +
    +

    2.1.2. Access functions

    size_max is the dimension of the input array, which should be -equal of larger than the value given in the table of section 2. +equal of larger than the value given in the table of section 2.

    -
    -
    2.1.2.1. C interface
    +
    +
    2.1.2.1. C interface
    qmckl_exit_code
    @@ -1147,8 +1160,8 @@ function returns true.
     
    -
    -
    2.1.2.2. Fortran interface
    +
    +
    2.1.2.2. Fortran interface
    interface
    @@ -1332,8 +1345,8 @@ function returns true.
     
    -
    -

    2.2. Computed data

    +
    +

    2.2. Computed data

    The following data is computed as described in the next sections: @@ -1408,8 +1421,8 @@ The following data is computed as described in the next sections:

    -
    -

    2.2.1. After initialization

    +
    +

    2.2.1. After initialization

    When the basis set is completely entered, extra data structures may be @@ -1423,8 +1436,8 @@ the context.

    -
    -

    2.2.2. TODO HPC-specific data structures

    +
    +

    2.2.2. TODO HPC-specific data structures

    For faster access, we provide extra arrays for the shell information as: @@ -1454,8 +1467,8 @@ which is a matrix-vector product.

    -
    -

    2.2.3. Access functions

    +
    +

    2.2.3. Access functions

    qmckl_exit_code
    @@ -1468,7 +1481,7 @@ which is a matrix-vector product.
     

    Returns the array of values, gradients an Laplacian of primitive basis functions evaluated at the current coordinates. -See section 3.2. +See section 3.2.

    @@ -1481,7 +1494,7 @@ See section 3.2.

    Returns the array of values, gradients an Laplacian of contracted shells -evaluated at the current coordinates. See section 3.3. +evaluated at the current coordinates. See section 3.3.

    @@ -1495,7 +1508,7 @@ evaluated at the current coordinates. See section 3.3.

    Returns the array of values, gradients an Laplacian of the atomic orbitals evaluated at the current coordinates. -See section 5. +See section 5.

    @@ -1520,7 +1533,7 @@ Uses the given array to compute the VGL.

    Returns the array of values of the atomic orbitals evaluated at -the current coordinates. See section 5. +the current coordinates. See section 5.

    @@ -1539,12 +1552,12 @@ Uses the given array to compute the value.

    -
    -

    3. Radial part

    +
    +

    3. Radial part

    -
    -

    3.1. General functions for Gaussian basis functions

    +
    +

    3.1. General functions for Gaussian basis functions

    qmckl_ao_gaussian_vgl computes the values, gradients and @@ -1717,10 +1730,10 @@ Requirements:

    -
    -

    3.2. Computation of primitives

    +
    +

    3.2. Computation of primitives

    - +
    @@ -1881,10 +1894,10 @@ Requirements: -
    -

    3.3. Computation of shells

    +
    +

    3.3. Computation of shells

    -
    +
    @@ -2138,10 +2151,276 @@ Requirements: + +
    +

    3.4. Hessian

    +
    +

    +Computes the Hessian of the shells. The shell_hessian[:][:][3][:] component is reserved for the derivative of the Laplacian of the shells. +

    +\begin{eqnarray} +\nabla_n \nabla_m v_i &=& 4 a_i^2 (X_n-R_n)(X_m - R_m)v_i -\delta_{n,m}2a_i v_i\\ +\nabla_m \nabla^2 v_i &=& 8 a_i^2 (X_m-R_m)v_i -2a_i^2 (4|X-R|^2 a_i -6)(X_m-R_m)v_i = 20 a_i^2 (X_m-R_m)v_i - 8a_i^3 |X-R|^2 (X_m-R_m) v_i +\end{eqnarray}
    -
    -

    4. Polynomial part

    +
    +

    3.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_ao_basis_shell_hessian (qmckl_context context,
    +                              double* const shell_hessian,
    +                              const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    3.4.2. Compute

    +
    +
    + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    prim_numint64_tinNumber of primitives
    shell_numint64_tinNumber of shells
    point_numint64_tinNumber of points
    nucl_numint64_tinNumber of nuclei
    nucleus_shell_numint64_t[nucl_num]inNumber of shells for each nucleus
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_rangedouble[nucl_num]inRange of the nucleus
    shell_prim_indexint64_t[shell_num]inIndex of the 1st primitive of each shell
    shell_prim_numint64_t[shell_num]inNumber of primitives per shell
    coorddouble[3][point_num]inCoordinates
    nucl_coorddouble[3][nucl_num]inNuclear coordinates
    expodouble[prim_num]inExponents of the primitives
    coef_normalizeddouble[prim_num]inCoefficients of the primitives
    shell_hessiandouble[point_num][3][4][shell_num]outHessian of the shells
    + +
    +
    function qmckl_compute_ao_basis_shell_gaussian_hessian( &
    +     context, prim_num, shell_num, point_num, nucl_num,       &
    +     nucleus_shell_num, nucleus_index, nucleus_range,         &
    +     shell_prim_index, shell_prim_num, coord, nucl_coord,     &
    +     expo, coef_normalized, shell_hessian)                        &
    +     bind(C) result(info)
    +
    +  use qmckl_constants
    +  use qmckl, only: qmckl_get_numprec_precision
    +
    +  implicit none
    +  integer (qmckl_context), intent(in)  , value :: context
    +  integer (c_int64_t) , intent(in)  , value :: prim_num
    +  integer (c_int64_t) , intent(in)  , value :: shell_num
    +  integer (c_int64_t) , intent(in)  , value :: point_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)          :: nucleus_shell_num(nucl_num)
    +  integer (c_int64_t) , intent(in)          :: nucleus_index(nucl_num)
    +  real    (c_double ) , intent(in)          :: nucleus_range(nucl_num)
    +  integer (c_int64_t) , intent(in)          :: shell_prim_index(shell_num)
    +  integer (c_int64_t) , intent(in)          :: shell_prim_num(shell_num)
    +  real    (c_double ) , intent(in)          :: coord(point_num,3)
    +  real    (c_double ) , intent(in)          :: nucl_coord(nucl_num,3)
    +  real    (c_double ) , intent(in)          :: expo(prim_num)
    +  real    (c_double ) , intent(in)          :: coef_normalized(prim_num)
    +  real    (c_double ) , intent(out)         :: shell_hessian(shell_num,4,3,point_num)
    +  integer(qmckl_exit_code) :: info
    +
    +  double precision :: xyz(3)
    +
    +  integer*8 :: inucl, iprim, ipoint, ishell
    +  integer*8 :: ishell_start, ishell_end
    +  integer*8 :: iprim_start , iprim_end, i, j
    +  double precision :: x, y, z, two_a, ar2, r2, v, cutoff
    +
    +  info = QMCKL_SUCCESS
    +
    +  ! Don't compute exponentials when the result will be almost zero.
    +  cutoff = qmckl_get_numprec_precision(context)
    +  cutoff = dlog(2.d0**(cutoff-2))
    +
    +  do ipoint = 1, point_num
    +
    +     do inucl=1,nucl_num
    +
    +        xyz(1) = coord(ipoint,1) - nucl_coord(inucl,1)
    +        xyz(2) = coord(ipoint,2) - nucl_coord(inucl,2)
    +        xyz(3) = coord(ipoint,3) - nucl_coord(inucl,3)
    +
    +        r2 = xyz(1)*xyz(1) + xyz(2)*xyz(2) + xyz(3)*xyz(3)
    +
    +        if (r2 > cutoff*nucleus_range(inucl)) then
    +           cycle
    +        end if
    +
    +        ! C is zero-based, so shift bounds by one
    +        ishell_start = nucleus_index(inucl) + 1
    +        ishell_end   = nucleus_index(inucl) + nucleus_shell_num(inucl)
    +
    +        do ishell=ishell_start, ishell_end
    +
    +           do i = 1, 4
    +              do j = 1, 3
    +                 shell_hessian(ishell, i, j, ipoint) = 0.d0
    +              end do
    +           end do 
    +
    +           iprim_start = shell_prim_index(ishell) + 1
    +           iprim_end   = shell_prim_index(ishell) + shell_prim_num(ishell)
    +
    +           do iprim = iprim_start, iprim_end
    +
    +              ar2 = expo(iprim)*r2
    +              if (ar2 > cutoff) then
    +                 cycle
    +              end if
    +
    +              v = coef_normalized(iprim) * dexp(-ar2)
    +              two_a = 2.d0 * expo(iprim)
    +
    +              do i = 1, 3
    +                 do j = 1, 3
    +                    if (i == j) then
    +                        shell_hessian(ishell, i, j, ipoint) = &
    +                              shell_hessian(ishell, i, j, ipoint) - two_a * v
    +                    end if
    +                    shell_hessian(ishell, i, j, ipoint) = &
    +                         shell_hessian(ishell, i, j, ipoint) + two_a * two_a * xyz(i) * xyz(j) * v
    +
    +                 end do
    +                 shell_hessian(ishell,4,i,ipoint) = shell_hessian(ishell,4,i,ipoint) &
    +                      + (5.d0 * two_a * two_a * xyz(i) &
    +                      - two_a * two_a * two_a * r2 * xyz(i)) * v
    +              end do
    +
    +           end do
    +
    +        end do
    +     end do
    +
    +  end do
    +
    +end function qmckl_compute_ao_basis_shell_gaussian_hessian
    +
    +
    +
    +
    +
    +
    + +
    +

    4. Polynomial part

    Going from the atomic basis set to AOs implies a systematic @@ -2161,8 +2440,8 @@ f & : & f_{xxx}, f_{xxy}, f_{xxz}, f_{xyy}, f_{xyz}, f_{xzz}, f_{yyy}, f_{yyz}, \end{eqnarray}

    -
    -

    4.1. General functions for Powers of \(x-X_i\)

    +
    +

    4.1. General functions for Powers of \(x-X_i\)

    The qmckl_ao_power function computes all the powers of the n @@ -2174,7 +2453,7 @@ the \(n\) points: \[ P_{ik} = X_i^k \]

    - +
    @@ -2315,8 +2594,8 @@ Requirements: -
    -

    4.2. General functions for Value, Gradient and Laplacian of a polynomial

    +
    +

    4.2. General functions for Value, Gradient and Laplacian of a polynomial

    A polynomial is centered on a nucleus \(\mathbf{R}_i\) @@ -2361,7 +2640,7 @@ Laplacians at a given point in space, of all polynomials with an angular momentum up to lmax.

    -
    +
    @@ -2474,6 +2753,7 @@ For example, with a=0, b=2 and c=1 the string is "yyz"
    qmckl_exit_code qmckl_ao_polynomial_vgl (
    +      Type Variable,
           const qmckl_context context,
           const double* X,
           const double* R,
    @@ -2488,6 +2768,7 @@ For example, with a=0, b=2 and c=1 the string is "yyz"
     
     
    qmckl_exit_code qmckl_ao_polynomial_vgl_doc (
    +      Type Variable,
           const qmckl_context context,
           const double* X,
           const double* R,
    @@ -2661,6 +2942,7 @@ For example, with a=0, b=2 and c=1 the string is "yyz"
     
     
    qmckl_exit_code qmckl_ao_polynomial_transp_vgl (
    +      Type Variable,
           const qmckl_context context,
           const double* X,
           const double* R,
    @@ -2675,6 +2957,7 @@ For example, with a=0, b=2 and c=1 the string is "yyz"
     
     
    qmckl_exit_code qmckl_ao_polynomial_transp_vgl_doc (
    +      Type Variable,
           const qmckl_context context,
           const double* X,
           const double* R,
    @@ -3155,14 +3438,218 @@ For example, with a=0, b=2 and c=1 the string is "yyz"
     
    + +
    +

    4.3. Hessian

    +
    +

    +Compute the Hessian of the polynomial part of the atomic orbitals. Similarly to the shells, the hessian[:][3][:] component is reserved for the derivative of the Laplacian. +

    + + + +
    + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    Xdouble[3]inArray containing the coordinates of the points
    Rdouble[3]inArray containing the x,y,z coordinates of the center
    lmaxint32_tinMaximum angular momentum
    nint64_tinoutNumber of computed polynomials
    hessiandouble[ldv][4][3]outHessian of the polynomials
    + +
    +
    function qmckl_compute_ao_polynomial_hessian_doc (context,    &
    +     X, R, lmax, n, hessian) &
    +     bind(C) result(info)
    +  use qmckl_constants
    +  implicit none
    +
    +  integer (qmckl_context), intent(in)  , value :: context
    +  real    (c_double ) , intent(in)          :: X(3)
    +  real    (c_double ) , intent(in)          :: R(3)
    +  integer (c_int32_t) , intent(in)  , value :: lmax
    +  integer (c_int64_t) , intent(inout)        :: n
    +  real    (c_double ) , intent(out)         :: hessian(3,4,(lmax+1)*(lmax+2)*(lmax+3)/6)
    +
    +  integer(qmckl_exit_code) :: info
    +
    +  integer           :: i,j,m,k
    +  integer           :: a,b,c,d
    +  double precision  :: Y(3)
    +  double precision  :: pows(-2:lmax,3)
    +  double precision  :: xy, yz, xz
    +  double precision  :: da, db, dc, dd
    +
    +  info = 0
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (lmax < 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +
    +  ! The shift below is such that polynomials will not make the AO equal to zero at the nodes of the orbitals
    +  do i=1,3
    +     Y(i) = (X(i) - R(i)) + 1.d-20
    +  end do
    +
    +  if (lmax == 0) then
    +     do k = 1, 3
    +        do m = 1, 3
    +           hessian(k,m,1) = 0.d0
    +        end do
    +      end do
    +     n=1
    +  else if (lmax > 0) then
    +     pows(-2:0,1:3) = 1.d0
    +     do i=1,lmax
    +        pows(i,1) = pows(i-1,1) * Y(1)
    +        pows(i,2) = pows(i-1,2) * Y(2)
    +        pows(i,3) = pows(i-1,3) * Y(3)
    +     end do
    +
    +     hessian(1:3,1:4,1:4) = 0.d0
    +
    +     n=4
    +  endif
    +
    +  ! l>=2
    +  dd = 2.d0
    +  do d=2,lmax
    +     da = dd
    +     do a=d,0,-1
    +        db = dd-da
    +        do b=d-a,0,-1
    +           c  = d  - a  - b
    +           dc = dd - da - db
    +           n = n+1
    +
    +           xy = pows(a,1) * pows(b,2)
    +           yz = pows(b,2) * pows(c,3)
    +           xz = pows(a,1) * pows(c,3)
    +
    +           xy = dc * xy
    +           xz = db * xz
    +           yz = da * yz
    +
    +          hessian(1,1,n) = da * (da-1.d0) * pows(a-2,1) * pows(b,2) * pows(c,3)
    +          hessian(2,2,n) = db * (db-1.d0) * pows(a,1) * pows(b-2,2) * pows(c,3)
    +          hessian(3,3,n) = dc * (dc-1.d0) * pows(a,1) * pows(b,2) * pows(c-2,3)
    +
    +          hessian(1,2,n) = da * db * pows(a-1,1) * pows(b-1,2) * pows(c,3)
    +          hessian(2,1,n) = da * db * pows(a-1,1) * pows(b-1,2) * pows(c,3)
    +
    +          hessian(1,3,n) = da * dc * pows(a-1,1) * pows(b,2) * pows(c-1,3)
    +          hessian(3,1,n) = da * dc * pows(a-1,1) * pows(b,2) * pows(c-1,3)
    +
    +          hessian(2,3,n) = db * dc * pows(a,1) * pows(b-1,2) * pows(c-1,3)
    +          hessian(3,2,n) = db * dc * pows(a,1) * pows(b-1,2) * pows(c-1,3)
    +
    +          hessian(1,4,n) = (da * db * (db-1.d0) * pows(a-1,1) * pows(b-2,2) * pows(c,3)) + &
    +                           (da * dc * (dc-1.d0) * pows(a-1,1) * pows(b,2) * pows(c-2,3))
    +
    +          hessian(2,4,n) = (db * da * (da-1.d0) * pows(a-2,1) * pows(b-1,2) * pows(c,3)) + &
    +                           (db * dc * (dc-1.d0) * pows(a,1) * pows(b-1,2) * pows(c-2,3))
    +
    +          hessian(3,4,n) = (dc * da * (da-1.d0) * pows(a-2,1) * pows(b,2) * pows(c-1,3)) + &
    +                           (dc * db * (db-1.d0) * pows(a,1) * pows(b-2,2) * pows(c-1,3))
    +
    +          if (da > 2) then
    +            hessian(1,4,n) = hessian(1,4,n) + (da * (da-1.d0) * (da-2.d0) * &
    +                 pows(a-3,1) * pows(b,2) * pows(c,3))
    +          end if
    +          if (db > 2) then
    +            hessian(2,4,n) = hessian(2,4,n) + (db * (db-1.d0) * (db-2.d0) * &
    +                 pows(a,1) * pows(b-3,2) * pows(c,3))
    +          end if
    +          if (dc > 2) then
    +            hessian(3,4,n) = hessian(3,4,n) + (dc * (dc-1.d0) * (dc-2.d0) * &
    +                 pows(a,1) * pows(b,2) * pows(c-3,3))
    +          end if
    +
    +           db = db - 1.d0
    +        end do
    +        da = da - 1.d0
    +     end do
    +     dd = dd + 1.d0
    +  end do
    +
    +  info = QMCKL_SUCCESS
    +
    +end function qmckl_compute_ao_polynomial_hessian_doc
    +
    +
    +
    +
    -
    -

    5. Combining radial and polynomial parts

    +
    +

    5. Combining radial and polynomial parts

    -
    -

    5.1. Determination of nucleus ranges

    +
    +

    5.1. Determination of nucleus ranges

    The range of a nucleus is defined as the distance beyond which all @@ -3328,14 +3815,14 @@ of bits of precision (1-53), a range is given.

    -
    -

    5.2. Values only

    +
    +

    5.2. Values only

    -
    -

    5.2.1. Unoptimized version

    +
    +

    5.2.1. Unoptimized version

    - +
    @@ -3575,10 +4062,10 @@ of bits of precision (1-53), a range is given. -
    -

    5.2.2. HPC version

    +
    +

    5.2.2. HPC version

    -
    +
    @@ -3736,8 +4223,8 @@ of bits of precision (1-53), a range is given. -
    -

    5.2.3. Interfaces

    +
    +

    5.2.3. Interfaces

    qmckl_exit_code qmckl_compute_ao_value_doc (
    @@ -3786,14 +4273,14 @@ of bits of precision (1-53), a range is given.
     
    -
    -

    5.3. Value, gradients, Laplacian

    +
    +

    5.3. Value, gradients, Laplacian

    -
    -

    5.3.1. Reference version

    +
    +

    5.3.1. Reference version

    -
    +
    @@ -4061,10 +4548,10 @@ of bits of precision (1-53), a range is given. -
    -

    5.3.2. HPC version

    +
    +

    5.3.2. HPC version

    -
    +
    @@ -4223,8 +4710,8 @@ of bits of precision (1-53), a range is given. -
    -

    5.3.3. Interfaces

    +
    +

    5.3.3. Interfaces

    qmckl_exit_code qmckl_compute_ao_vgl_doc (
    @@ -4272,11 +4759,313 @@ of bits of precision (1-53), a range is given.
     
    + +
    +

    5.4. AO Hessian

    +
    +

    +Computes the Hessian of the AOs. For this, it needs the Hessian of the shells, as well as the Hessian of the polynomials. +The ao_hessian[:][:][4][:] component is reserved for the derivative of the Laplacian of the AOs. +

    +
    + +
    +

    5.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_ao_basis_ao_hessian(qmckl_context context,
    +                          double* const ao_hessian,
    +                          const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.4.2. Compute

    +
    +
    + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    ao_numint64_tinNumber of AOs
    shell_numint64_tinNumber of shells
    point_numint64_tinNumber of points
    nucl_numint64_tinNumber of nuclei
    coorddouble[3][point_num]inCoordinates
    nucl_coorddouble[3][nucl_num]inNuclear coordinates
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_shell_numint64_t[nucl_num]inNumber of shells per nucleus
    nucleus_rangedouble[nucl_num]inRange beyond which all is zero
    nucleus_max_ang_momint32_t[nucl_num]inMaximum angular momentum per nucleus
    shell_ang_momint32_t[shell_num]inAngular momentum of each shell
    ao_factordouble[ao_num]inNormalization factor of the AOs
    shell_vgldouble[point_num][5][shell_num]inValue, gradients and Laplacian of the shells
    shell_hessiandouble[point_num][3][4][shell_num]inHessian of the shells
    ao_hessiandouble[3][point_num][4][ao_num]outHessian of the AOs
    + +
    +
    function qmckl_compute_ao_hessian_doc(context, &
    +     ao_num, shell_num, point_num, nucl_num, &
    +     coord, nucl_coord, nucleus_index, nucleus_shell_num, &
    +     nucleus_range, nucleus_max_ang_mom, shell_ang_mom, &
    +     ao_factor, shell_vgl, shell_hessian, ao_hessian) &
    +     bind(C) result(info)
    +  use qmckl_constants
    +  use qmckl, only : qmckl_ao_polynomial_hessian, qmckl_ao_polynomial_vgl, qmckl_get_numprec_precision
    +  implicit none
    +  integer (qmckl_context), intent(in)  , value :: context
    +  integer (c_int64_t) , intent(in)  , value :: ao_num
    +  integer (c_int64_t) , intent(in)  , value :: shell_num
    +  integer (c_int64_t) , intent(in)  , value :: point_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  real    (c_double ) , intent(in)          :: coord(point_num,3)
    +  real    (c_double ) , intent(in)          :: nucl_coord(nucl_num,3)
    +  integer (c_int64_t) , intent(in)          :: nucleus_index(nucl_num)
    +  integer (c_int64_t) , intent(in)          :: nucleus_shell_num(nucl_num)
    +  real    (c_double ) , intent(in)          :: nucleus_range(nucl_num)
    +  integer (c_int32_t) , intent(in)          :: nucleus_max_ang_mom(nucl_num)
    +  integer (c_int32_t) , intent(in)          :: shell_ang_mom(shell_num)
    +  real    (c_double ) , intent(in)          :: ao_factor(ao_num)
    +  real    (c_double ) , intent(in)          :: shell_vgl(shell_num,5,point_num)
    +  real    (c_double ) , intent(in)          :: shell_hessian(shell_num,4,3,point_num)
    +  real    (c_double ) , intent(out)         :: ao_hessian(ao_num,4,point_num,3)
    +  integer(qmckl_exit_code) :: info
    +
    +  double precision  :: e_coord(3), n_coord(3)
    +  integer*8         :: n_poly
    +  integer           :: l, il, k, i, j
    +  integer*8         :: ipoint, inucl, ishell
    +  integer*8         :: ishell_start, ishell_end
    +  integer           :: lstart(0:20)
    +  double precision  :: x, y, z, r2
    +  double precision  :: cutoff
    +
    +  double precision, allocatable  :: poly_hessian(:,:,:), poly_vgl(:,:)
    +  integer         , allocatable  :: powers(:,:), ao_index(:)
    +
    +  allocate(poly_vgl(5,ao_num), poly_hessian(3,4,ao_num), powers(3,ao_num), ao_index(ao_num))
    +
    +  ! Pre-computed data
    +  do l=0,20
    +     lstart(l) = l*(l+1)*(l+2)/6 +1
    +  end do
    +
    +  k=1
    +  do inucl=1,nucl_num
    +     ishell_start = nucleus_index(inucl) + 1
    +     ishell_end   = nucleus_index(inucl) + nucleus_shell_num(inucl)
    +     do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        ao_index(ishell) = k
    +        k = k + lstart(l+1) - lstart(l)
    +     end do
    +  end do
    +  info = QMCKL_SUCCESS
    +
    +  ! Don't compute polynomials when the radial part is zero.
    +  cutoff = qmckl_get_numprec_precision(context)
    +  cutoff = dlog(2.d0**(cutoff-2))
    +
    +  !ao_hessian = 0.d0
    +
    +  do ipoint = 1, point_num
    +     e_coord(1) = coord(ipoint,1)
    +     e_coord(2) = coord(ipoint,2)
    +     e_coord(3) = coord(ipoint,3)
    +     ao_hessian(:,:,ipoint,:) = 0.d0
    +     do inucl=1,nucl_num
    +        n_coord(1) = nucl_coord(inucl,1)
    +        n_coord(2) = nucl_coord(inucl,2)
    +        n_coord(3) = nucl_coord(inucl,3)
    +
    +        ! Test if the point is in the range of the nucleus
    +        x = e_coord(1) - n_coord(1)
    +        y = e_coord(2) - n_coord(2)
    +        z = e_coord(3) - n_coord(3)
    +
    +        r2 = x*x + y*y + z*z
    +        if (r2 > cutoff*nucleus_range(inucl)) then
    +           !ao_hessian(:,:,ipoint,:) = 0.d0
    +           cycle
    +        end if
    +
    +        ! Compute polynomials
    +        info = qmckl_ao_polynomial_hessian(context, e_coord, n_coord, &
    +             nucleus_max_ang_mom(inucl), n_poly, poly_hessian)
    +
    +        info = qmckl_ao_polynomial_vgl(context, e_coord, n_coord, &
    +             nucleus_max_ang_mom(inucl), n_poly, powers, 3_8, &
    +             poly_vgl, 5_8)
    +
    +        ! Loop over shells
    +        ishell_start = nucleus_index(inucl) + 1
    +        ishell_end   = nucleus_index(inucl) + nucleus_shell_num(inucl)
    +        do ishell = ishell_start, ishell_end
    +           k = ao_index(ishell)
    +           l = shell_ang_mom(ishell)
    +           do il = lstart(l), lstart(l+1)-1
    +
    +              do i = 1, 3
    +                 do j = 1, 3
    +                    ao_hessian(k,j,ipoint,i) = (&
    +                         poly_hessian(j,i,il) * shell_vgl(ishell,1,ipoint) + &
    +                         poly_vgl(1,il) * shell_hessian(ishell,j,i,ipoint) + &
    +                         poly_vgl(j+1,il) * shell_vgl(ishell,i+1,ipoint) + &
    +                         poly_vgl(i+1,il) * shell_vgl(ishell,j+1,ipoint) &
    +                         ) * ao_factor(k)
    +                 end do
    +
    +                 ao_hessian(k,4,ipoint,i) = (&
    +                      poly_hessian(i,4,il) * shell_vgl(ishell,1,ipoint) + &
    +                      poly_vgl(1,il) * shell_hessian(ishell,4,i,ipoint) + &
    +                      poly_vgl(5,il) * shell_vgl(ishell,i+1,ipoint) + &
    +                      poly_vgl(i+1,il) * shell_vgl(ishell,5,ipoint) + &
    +                      2.d0 * (&
    +                      poly_hessian(1,i,il) * shell_vgl(ishell,2,ipoint) + &
    +                      poly_vgl(2,il) * shell_hessian(ishell,1,i,ipoint) + &
    +                      poly_hessian(2,i,il) * shell_vgl(ishell,3,ipoint) + &
    +                      poly_vgl(3,il) * shell_hessian(ishell,2,i,ipoint) + &
    +                      poly_hessian(3,i,il) * shell_vgl(ishell,4,ipoint) + &
    +                      poly_vgl(4,il) * shell_hessian(ishell,3,i,ipoint) &
    +                      )) * ao_factor(k)
    +
    +              end do
    +
    +              k = k+1
    +           end do
    +        end do
    +     end do
    +  end do
    +
    +  deallocate(poly_vgl, powers, poly_hessian, ao_index)
    +end function qmckl_compute_ao_hessian_doc
    +
    +
    +
    +
    +

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_blas.html b/qmckl_blas.html index ff39d29..1d9e44e 100644 --- a/qmckl_blas.html +++ b/qmckl_blas.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + BLAS functions @@ -258,56 +258,56 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    -

    -
    +
    +

    -

    +

    Basic linear algebra data types and operations are described in this file. The data types are private, so that HPC implementations can use @@ -321,12 +321,12 @@ are not intended to be passed to external codes.

    -
    -

    1. Data types

    +
    +

    1. Data types

    -
    -

    1.1. Vector

    +
    +

    1.1. Vector

    @@ -380,8 +380,8 @@ Allocates a new vector. If the allocation failed the size is zero. -
    -

    1.2. Matrix

    +
    +

    1.2. Matrix

    @@ -441,8 +441,8 @@ Allocates a new matrix. If the allocation failed the sizes are zero. -
    -

    1.3. Tensor

    +
    +

    1.3. Tensor

    @@ -509,16 +509,16 @@ is zero. -
    -

    1.4. Reshaping

    +
    +

    1.4. Reshaping

    Reshaping occurs in-place and the pointer to the data is copied.

    -
    -

    1.4.1. Vector -> Matrix

    +
    +

    1.4.1. Vector -> Matrix

    qmckl_matrix
    @@ -534,8 +534,8 @@ Reshapes a vector into a matrix.
     
    -
    -

    1.4.2. Vector -> Tensor

    +
    +

    1.4.2. Vector -> Tensor

    qmckl_tensor
    @@ -551,8 +551,8 @@ Reshapes a vector into a tensor.
     
    -
    -

    1.4.3. Matrix -> Vector

    +
    +

    1.4.3. Matrix -> Vector

    qmckl_vector
    @@ -566,8 +566,8 @@ Reshapes a matrix into a vector.
     
    -
    -

    1.4.4. Matrix -> Tensor

    +
    +

    1.4.4. Matrix -> Tensor

    qmckl_tensor
    @@ -583,8 +583,8 @@ Reshapes a matrix into a tensor.
     
    -
    -

    1.4.5. Tensor -> Vector

    +
    +

    1.4.5. Tensor -> Vector

    qmckl_vector
    @@ -598,8 +598,8 @@ Reshapes a tensor into a vector.
     
    -
    -

    1.4.6. Tensor -> Matrix

    +
    +

    1.4.6. Tensor -> Matrix

    qmckl_matrix
    @@ -616,8 +616,8 @@ Reshapes a tensor into a vector.
     
    -
    -

    1.5. Access macros

    +
    +

    1.5. Access macros

    Macros are provided to ease the access to vectors, matrices and @@ -642,12 +642,12 @@ For example:

    -
    -

    1.6. Set all elements

    +
    +

    1.6. Set all elements

    -
    -

    1.6.1. Vector

    +
    +

    1.6.1. Vector

    qmckl_vector
    @@ -657,8 +657,8 @@ For example:
     
    -
    -

    1.6.2. Matrix

    +
    +

    1.6.2. Matrix

    qmckl_matrix
    @@ -668,8 +668,8 @@ For example:
     
    -
    -

    1.6.3. Tensor

    +
    +

    1.6.3. Tensor

    qmckl_tensor
    @@ -680,8 +680,8 @@ For example:
     
    -
    -

    1.7. Copy to/from to double*

    +
    +

    1.7. Copy to/from to double*

    qmckl_exit_code
    @@ -763,8 +763,8 @@ Converts a double* to a tensor.
     
    -
    -

    1.8. Allocate and copy to double*

    +
    +

    1.8. Allocate and copy to double*

    double* qmckl_alloc_double_of_vector(const qmckl_context context,
    @@ -788,12 +788,12 @@ Converts a double* to a tensor.
     
    -
    -

    2. Matrix operations

    +
    +

    2. Matrix operations

    -
    -

    2.1. qmckl_dgemm

    +
    +

    2.1. qmckl_dgemm

    Matrix multiplication with a BLAS interface: @@ -805,7 +805,7 @@ Matrix multiplication with a BLAS interface: \]

    -
    +
    @@ -964,8 +964,8 @@ Requirements: -
    -

    2.2. qmckl_dgemm_safe

    +
    +

    2.2. qmckl_dgemm_safe

    "Size-safe" proxy function with the same functionality as qmckl_dgemm @@ -974,7 +974,7 @@ are required primarily for the Python API, where compatibility with NumPy arrays implies that sizes of the input and output arrays are provided.

    -
    +
    @@ -1160,8 +1160,8 @@ Requirements: -
    -

    2.3. qmckl_matmul

    +
    +

    2.3. qmckl_matmul

    Matrix multiplication using the qmckl_matrix data type: @@ -1173,7 +1173,7 @@ Matrix multiplication using the qmckl_matrix data type: \]

    -
    +
    @@ -1267,8 +1267,8 @@ Matrix multiplication using the qmckl_matrix data type: -
    -

    2.4. qmckl_adjugate

    +
    +

    2.4. qmckl_adjugate

    Given a matrix \(\mathbf{A}\), the adjugate matrix @@ -1286,7 +1286,7 @@ of \(\mathbf{A}\). See also: https://en.wikipedia.org/wiki/Adjugate_matrix

    -
    +
    @@ -1482,8 +1482,8 @@ determinant with the inverse: -
    -

    2.5. qmckl_adjugate_safe

    +
    +

    2.5. qmckl_adjugate_safe

    "Size-safe" proxy function with the same functionality as qmckl_adjugate @@ -1493,7 +1493,7 @@ NumPy arrays implies that sizes of the input and output arrays are provided.

    -
    +
    @@ -1615,13 +1615,13 @@ LAPACK library.

    -
    -

    2.5.1. C interface

    +
    +

    2.5.1. C interface

    -
    -

    2.6. qmckl_transpose

    +
    +

    2.6. qmckl_transpose

    Transposes a matrix: \(A^\dagger_{ji} = A_{ij}\). @@ -1682,8 +1682,8 @@ Transposes a matrix: \(A^\dagger_{ji} = A_{ij}\).

    -
    -

    3. Utilities

    +
    +

    3. Utilities

    Trick to make MKL efficient on AMD @@ -1701,7 +1701,7 @@ Trick to make MKL efficient on AMD

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_context.html b/qmckl_context.html index 979827e..c81b457 100644 --- a/qmckl_context.html +++ b/qmckl_context.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Context @@ -226,21 +226,25 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context handling

    +
    +

    1. Context handling

    The context variable is a handle for the state of the library, @@ -253,7 +257,7 @@ A value of QMCKL_NULL_CONTEXT for the context is equivalent to a

    -
    typedef int64_t qmckl_context ;
    +
    typedef int64_t qmckl_context ;
     #define QMCKL_NULL_CONTEXT (qmckl_context) 0
     
    @@ -271,8 +275,8 @@ and ctx is a qmckl_context_struct* pointer.

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    The qmcklextra pointer lets the other implementation of the library @@ -308,7 +312,7 @@ to be recomputed. The date is incremented when the context is touched.

    When a new element is added to the context, the functions -qmckl_context_create qmckl_context_destroy and qmckl_context_copy +qmckl_context_create qmckl_context_destroy and qmckl_context_copy should be updated in order to make deep copies.

    @@ -327,10 +331,15 @@ using the following function. This has the effect to increment the date of the context.

    + +
    +

    1.1.1. Fortran binding

    +
    -
    -

    1.2. Creation

    + +
    +

    1.2. Creation

    To create a new context, qmckl_context_create() should be used. @@ -347,8 +356,8 @@ To create a new context, qmckl_context_create() should be used.

    -
    -

    1.3. Locking

    +
    +

    1.3. Locking

    For thread safety, the context may be locked/unlocked. The lock is @@ -364,8 +373,8 @@ number of times the thread has locked it is saved in the

    -
    -

    1.4. TODO Copy

    +
    +

    1.4. TODO Copy

    qmckl_context_copy makes a deep copy of a context. It returns @@ -373,8 +382,8 @@ number of times the thread has locked it is saved in the

    -
    -

    1.5. Destroy

    +
    +

    1.5. Destroy

    The context is destroyed with qmckl_context_destroy, leaving the ancestors untouched. @@ -392,7 +401,7 @@ It frees the context, and returns the previous context.

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_determinant.html b/qmckl_determinant.html index 63309d9..af0b9ee 100644 --- a/qmckl_determinant.html +++ b/qmckl_determinant.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Slater Determinant @@ -226,32 +226,32 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following arrays are stored in the context: @@ -437,8 +437,8 @@ Computed data:

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    typedef struct qmckl_determinant_struct {
    @@ -506,8 +506,8 @@ this mechanism.
     
    -
    -

    1.2. Access functions

    +
    +

    1.2. Access functions

    When all the data for the slater determinants have been provided, the following @@ -521,8 +521,8 @@ function returns true.

    -
    -

    1.3. Initialization functions

    +
    +

    1.3. Initialization functions

    To set the basis set, all the following functions need to be @@ -545,24 +545,24 @@ computed to accelerate the calculations.

    -
    -

    1.4. Fortran Interfaces

    +
    +

    1.4. Fortran Interfaces

    -
    -

    1.5. Test

    +
    +

    1.5. Test

    -
    -

    2. Computation

    +
    +

    2. Computation

    -
    -

    2.1. Determinant matrix

    +
    +

    2.1. Determinant matrix

    -
    -

    2.1.1. Get

    +
    +

    2.1.1. Get

    qmckl_exit_code qmckl_get_det_vgl_alpha(qmckl_context context, double* const det_vgl_alpha);
    @@ -572,14 +572,14 @@ computed to accelerate the calculations.
     
    -
    -

    2.1.2. Provide

    +
    +

    2.1.2. Provide

    -
    -

    2.1.3. Compute alpha

    +
    +

    2.1.3. Compute alpha

    - +
    @@ -753,10 +753,10 @@ computed to accelerate the calculations. -
    -

    2.1.4. Compute beta

    +
    +

    2.1.4. Compute beta

    -
    +
    @@ -930,18 +930,18 @@ computed to accelerate the calculations. -
    -

    2.1.5. Test

    +
    +

    2.1.5. Test

    -
    -

    2.2. Inverse of Determinant matrix

    +
    +

    2.2. Inverse of Determinant matrix

    -
    -

    2.2.1. Get

    +
    +

    2.2.1. Get

    qmckl_exit_code qmckl_get_det_inv_matrix_alpha(qmckl_context context, double* const det_inv_matrix_alpha);
    @@ -955,14 +955,14 @@ computed to accelerate the calculations.
     
    -
    -

    2.2.2. Provide

    +
    +

    2.2.2. Provide

    -
    -

    2.2.3. Compute alpha

    +
    +

    2.2.3. Compute alpha

    -
    +
    @@ -1124,10 +1124,10 @@ computed to accelerate the calculations. -
    -

    2.2.4. Compute beta

    +
    +

    2.2.4. Compute beta

    -
    +
    @@ -1294,7 +1294,7 @@ computed to accelerate the calculations.

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_distance.html b/qmckl_distance.html index 2a7a6ea..f208118 100644 --- a/qmckl_distance.html +++ b/qmckl_distance.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - +Inter-particle distances @@ -258,54 +258,54 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Squared distance

    +
    +

    1. Squared distance

    -
    -

    1.1. qmckl_distance_sq

    +
    +

    1.1. qmckl_distance_sq

    qmckl_distance_sq computes the matrix of the squared distances @@ -318,7 +318,7 @@ between all pairs of points in two sets, one point within each set: \]

    -
    +
    @@ -590,8 +590,8 @@ Requirements: -
    -

    1.1.1. Performance

    +
    +

    1.1.1. Performance

    This function is more efficient when A and B are @@ -601,12 +601,12 @@ transposed.

    -
    -

    2. Distance

    +
    +

    2. Distance

    -
    -

    2.1. qmckl_distance

    +
    +

    2.1. qmckl_distance

    qmckl_distance computes the matrix of the distances between all @@ -624,7 +624,7 @@ If the input array is normal ('N'), the xyz coordinates are in the leading dimension: [n][3] in C and (3,n) in Fortran.

    -
    +
    @@ -725,8 +725,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
    -
    -

    2.1.1. Requirements

    +
    +

    2.1.1. Requirements

    • context is not QMCKL_NULL_CONTEXT
    • @@ -744,8 +744,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
    -
    -

    2.1.2. C header

    +
    +

    2.1.2. C header

    qmckl_exit_code qmckl_distance (
    @@ -765,8 +765,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
     
    -
    -

    2.1.3. Source

    +
    +

    2.1.3. Source

    function qmckl_distance(context, transa, transb, m, n, &
    @@ -916,8 +916,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
     
    -
    -

    2.1.4. Performance

    +
    +

    2.1.4. Performance

    This function is more efficient when A and B are transposed. @@ -927,12 +927,12 @@ This function is more efficient when A and B are trans

    -
    -

    3. Rescaled Distance

    +
    +

    3. Rescaled Distance

    -
    -

    3.1. qmckl_distance_rescaled

    +
    +

    3.1. qmckl_distance_rescaled

    qmckl_distance_rescaled computes the matrix of the rescaled distances between all @@ -950,7 +950,7 @@ If the input array is normal ('N'), the xyz coordinates are in the leading dimension: [n][3] in C and (3,n) in Fortran.

    - +
    @@ -1058,8 +1058,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
    -
    -

    3.1.1. Requirements

    +
    +

    3.1.1. Requirements

    • context is not QMCKL_NULL_CONTEXT
    • @@ -1077,8 +1077,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
    -
    -

    3.1.2. C header

    +
    +

    3.1.2. C header

    qmckl_exit_code qmckl_distance_rescaled (
    @@ -1099,8 +1099,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
     
    -
    -

    3.1.3. Source

    +
    +

    3.1.3. Source

    function qmckl_distance_rescaled(context, transa, transb, m, n, &
    @@ -1253,8 +1253,8 @@ the leading dimension: [n][3] in C and (3,n) in Fortra
     
    -
    -

    3.1.4. Performance

    +
    +

    3.1.4. Performance

    This function is more efficient when A and B are transposed. @@ -1263,12 +1263,12 @@ This function is more efficient when A and B are trans

    -
    -

    4. Rescaled Distance Derivatives

    +
    +

    4. Rescaled Distance Derivatives

    -
    -

    4.1. qmckl_distance_rescaled_gl

    +
    +

    4.1. qmckl_distance_rescaled_gl

    qmckl_distance_rescaled_gl computes the matrix of the gradient and Laplacian of the @@ -1323,7 +1323,7 @@ If the input array is normal ('N'), the xyz coordinates are in the leading dimension: [n][3] in C and (3,n) in Fortran.

    - +
    @@ -1643,7 +1643,7 @@ This function is more efficient when A and B are trans

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_electron.html b/qmckl_electron.html index 023f9d6..b917412 100644 --- a/qmckl_electron.html +++ b/qmckl_electron.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - +Electrons @@ -258,59 +258,59 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following data stored in the context: @@ -451,8 +451,8 @@ Computed data:

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    @@ -521,8 +521,8 @@ this mechanism.
     
    -
    -

    1.2. Initialization functions

    +
    +

    1.2. Initialization functions

    To set the data relative to the electrons in the context, the @@ -595,8 +595,8 @@ in the context.

    -
    -

    1.3. Access functions

    +
    +

    1.3. Access functions

    Access functions return QMCKL_SUCCESS when the data has been @@ -608,12 +608,12 @@ contains the requested data. Otherwise, this variable is untouched.

    -
    -

    1.3.1. Number of electrons

    +
    +

    1.3.1. Number of electrons

    -
    -

    1.3.2. Number of walkers

    +
    +

    1.3.2. Number of walkers

    A walker is a set of electron coordinates that are arguments of @@ -622,8 +622,8 @@ the wave function. walk_num is the number of walkers.

    -
    -

    1.3.3. Electron coordinates

    +
    +

    1.3.3. Electron coordinates

    Returns the current electron coordinates. The pointer is assumed @@ -688,8 +688,8 @@ current points.

    -
    -

    1.4. Test

    +
    +

    1.4. Test

    /* Reference input data */
    @@ -768,8 +768,8 @@ rc = qmckl_get_electron_coord (context, 'N'
     
    -
    -

    2. Computation

    +
    +

    2. Computation

    The computed data is stored in the context so that it can be reused @@ -782,12 +782,12 @@ current date is stored.

    -
    -

    2.1. Electron-electron distances

    +
    +

    2.1. Electron-electron distances

    -
    -

    2.1.1. Get

    +
    +

    2.1.1. Get

    qmckl_exit_code
    @@ -799,10 +799,10 @@ current date is stored.
     
    -
    -

    2.1.2. Compute

    +
    +

    2.1.2. Compute

    - +
    @@ -907,8 +907,8 @@ current date is stored. -
    -

    2.1.3. Test

    +
    +

    2.1.3. Test

    assert(qmckl_electron_provided(context));
    @@ -942,8 +942,8 @@ rc = qmckl_get_electron_ee_distance(context, ee_distance, walk_num * elec_num *
     
    -
    -

    2.2. Electron-electron potential

    +
    +

    2.2. Electron-electron potential

    ee_potential is given by @@ -961,8 +961,8 @@ distance.

    -
    -

    2.2.1. Get

    +
    +

    2.2.1. Get

    qmckl_exit_code qmckl_get_electron_ee_potential(qmckl_context context, double* const ee_potential);
    @@ -971,10 +971,10 @@ distance.
     
    -
    -

    2.2.2. Compute

    +
    +

    2.2.2. Compute

    -
    +
    @@ -1090,8 +1090,8 @@ distance. -
    -

    2.2.3. Test

    +
    +

    2.2.3. Test

    double ee_potential[walk_num];
    @@ -1103,24 +1103,27 @@ rc = qmckl_get_electron_ee_potential(context, &(ee_potential[0]));
     
    -
    -

    2.3. Electron-nucleus distances

    +
    +

    2.3. Electron-nucleus distances

    -
    -

    2.3.1. Get

    +
    +

    2.3.1. Get

    -
    qmckl_exit_code qmckl_get_electron_en_distance(qmckl_context context, double* distance);
    +
    qmckl_exit_code
    +qmckl_get_electron_en_distance(qmckl_context context,
    +                               double* const distance,
    +                               const int64_t size_max);
     
    -
    -

    2.3.2. Compute

    +
    +

    2.3.2. Compute

    -
    +
    @@ -1227,8 +1230,8 @@ rc = qmckl_get_electron_ee_potential(context, &(ee_potential[0])); -
    -

    2.3.3. Test

    +
    +

    2.3.3. Test

    @@ -1248,7 +1251,7 @@ rc = qmckl_set_nucleus_coord (context, 'T',
     
     double en_distance[walk_num][elec_num][nucl_num];
     
    -rc = qmckl_get_electron_en_distance(context, &(en_distance[0][0][0]));
    +rc = qmckl_get_electron_en_distance(context, &(en_distance[0][0][0]), walk_num * elec_num * nucl_num);
     qmckl_check(context, rc);
     
     // (e,n,w) in Fortran notation
    @@ -1276,8 +1279,8 @@ rc = qmckl_get_electron_en_distance(context, &(en_distance[0][0][0]));
     
    -
    -

    2.4. Electron-nucleus potential

    +
    +

    2.4. Electron-nucleus potential

    en_potential stores the en potential energy @@ -1295,8 +1298,8 @@ distance and \[Z_A\] is the nuclear charge.

    -
    -

    2.4.1. Get

    +
    +

    2.4.1. Get

    qmckl_exit_code qmckl_get_electron_en_potential(qmckl_context context, double* const en_potential);
    @@ -1305,10 +1308,10 @@ distance and \[Z_A\] is the nuclear charge.
     
    -
    -

    2.4.2. Compute

    +
    +

    2.4.2. Compute

    -
    +
    @@ -1442,8 +1445,8 @@ distance and \[Z_A\] is the nuclear charge. -
    -

    2.4.3. Test

    +
    +

    2.4.3. Test

    double en_potential[walk_num];
    @@ -1456,14 +1459,14 @@ rc = qmckl_get_electron_en_potential(context, &(en_potential[0]));
     
    -
    -

    2.5. Generate initial coordinates

    +
    +

    2.5. Generate initial coordinates

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_error.html b/qmckl_error.html index 55c81c5..5b126a9 100644 --- a/qmckl_error.html +++ b/qmckl_error.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Error handling @@ -226,29 +226,29 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    -

    -
    +
    +

    -

    +

    The library should never make the calling programs abort, nor perform any input/output operations. This decision has to be taken @@ -259,7 +259,7 @@ by the developer of the code calling the library. All the functions return with an exit code, defined as

    -
    typedef int32_t qmckl_exit_code;
    +
    typedef int32_t qmckl_exit_code;
     
    @@ -276,7 +276,7 @@ error code is returned to the program. Here is the complete list of exit codes.

    -
    +
    @@ -484,8 +484,8 @@ string is assumed to be large enough to contain the error message -
    -

    1. Decoding errors

    +
    +

    1. Decoding errors

    To decode the error messages, qmckl_string_of_error converts an @@ -503,8 +503,8 @@ The text strings are extracted from the previous table.

    -
    -

    2. Data structure in context

    +
    +

    2. Data structure in context

    The strings are declared internally with a maximum fixed size to avoid @@ -527,8 +527,8 @@ dynamic memory allocation.

    -
    -

    3. Updating errors in the context

    +
    +

    3. Updating errors in the context

    The error is updated in the context using qmckl_set_error. @@ -547,8 +547,8 @@ explaining the error. The exit code can't be QMCKL_SUCCESS.

    -
    -

    4. Get the error

    +
    +

    4. Get the error

    Upon error, the error type and message can be obtained from the @@ -567,8 +567,8 @@ function name and message is mandatory.

    -
    -

    5. Failing

    +
    +

    5. Failing

    To make a function fail, the qmckl_failwith function should be @@ -605,8 +605,8 @@ For example, this function can be used as

    -
    -

    6. Last error

    +
    +

    6. Last error

    Returns a string describing the last error, using qmckl_get_error. @@ -618,13 +618,13 @@ Returns a string describing the last error, using qmckl_get_error.

    -
    -

    6.1. Fortran inteface

    +
    +

    6.1. Fortran inteface

    -
    -

    7. Helper functions for debugging

    +
    +

    7. Helper functions for debugging

    The following function prints to stderr an error message is the return code is @@ -650,14 +650,14 @@ It should be used as:

    -
    -

    7.1. Fortran inteface

    +
    +

    7.1. Fortran inteface

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_examples.html b/qmckl_examples.html index 9676e43..a2695f1 100644 --- a/qmckl_examples.html +++ b/qmckl_examples.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Code examples @@ -258,25 +258,25 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Overlap matrix in the MO basis

    +
    +

    1. Overlap matrix in the MO basis

    The focal point of this example is the numerical evaluation of the overlap @@ -329,8 +329,8 @@ code.

    -
    -

    1.1. Python

    +
    +

    1.1. Python

    In this example, we will compute numerically the overlap @@ -396,7 +396,7 @@ We fetch the nuclear coordinates from the context,

    -
    +
     8  +0.000000 +0.000000 +0.000000
     1  -1.430429 +0.000000 -1.107157
     1  +1.430429 +0.000000 -1.107157
    @@ -470,7 +470,7 @@ and thus obtain the matrix \(M_{ki} = \langle \mathbf{r}_k | \phi_i \rangle =
     
    -
    +
     Number of MOs:  201
     Number of grid points:  1728000
     Execution time :  5.577778577804565 seconds
    @@ -487,7 +487,7 @@ and finally we compute the overlap between all the MOs as
     
    -
    +
     [[ 9.88693941e-01  2.34719693e-03 -1.50518232e-08 ...  3.12084178e-09
       -5.81064929e-10  3.70130091e-02]
      [ 2.34719693e-03  9.99509628e-01  3.18930040e-09 ... -2.46888958e-10
    @@ -505,8 +505,8 @@ and finally we compute the overlap between all the MOs as
     
    -
    -

    1.2. C

    +
    +

    1.2. C

    In this example, electron-nucleus cusp fitting is added. @@ -652,7 +652,7 @@ rc = qmckl_get_nucleus_coord(context, 'N',

    -
    +
     8  +0.000000 +0.000000 +0.000000
     1  -1.430429 +0.000000 -1.107157
     1  +1.430429 +0.000000 -1.107157
    @@ -784,7 +784,7 @@ printf("Execution time : %f seconds\n", (af
     
    -
    +
     Number of MOs:  201
     Number of grid points:  1728000
     Execution time :  5.608000 seconds
    @@ -825,7 +825,7 @@ and finally we compute the overlap between all the MOs as
     
    -
    +
       0 0.988765 0.002336 0.000000 -0.000734 0.000000 0.000530 0.000000 0.000446 0.000000 -0.000000 -0.000511 -0.000000 -0.000267 0.000000 0.000000 0.001007 0.000000 0.000168 -0.000000 -0.000000 -0.000670 -0.000000 0.000000 -0.000251 -0.000261 -0.000000 -0.000000 -0.000000 -0.000397 -0.000000 -0.000810 0.000000 0.000231 -0.000000 -0.000000 0.000000 -0.000000
       ...
     200 0.039017 -0.013066 -0.000000 -0.001935 -0.000000 -0.003829 -0.000000 0.000996 -0.000000 0.000000 -0.003733 0.000000 0.000065 -0.000000 -0.000000 -0.002220 -0.000000 -0.001961 0.000000 0.000000 -0.004182 0.000000 -0.000000 -0.000165 -0.002445 0.000000 -0.000000 0.000000 0.001985 0.000000 0.001685 -0.000000 -0.002899 0.000000 0.000000 0.000000 -0.000000 0.002591 0.000000 -0.000000 0.000000 0.002385 0.000000 -0.011086 0.000000 -0.003885 0.000000 -0.000000 0.003602 -0.000000 0.000000 -0.003241 0.000000 0.000000 0.002613 -0.007344 -0.000000 -0.000000 0.000000 0.000017 0.000000 0.000000 0.000000 -0.008719 0.000000 -0.001358 -0.003233 0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.003778 0.000000 0.000000 -0.000000 0.000000 0.000000 -0.001190 0.000000 0.000000 -0.000000 0.005578 -0.000000 -0.001502 0.003899 -0.000000 -0.000000 0.000000 -0.003291 -0.001775 -0.000000 -0.002374 0.000000 -0.000000 -0.000000 -0.000000 -0.001290 -0.000000 0.002178 0.000000 0.000000 0.000000 -0.001252 0.000000 -0.000000 -0.000926 0.000000 -0.000000 -0.013130 -0.000000 0.012124 0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.025194 0.000343 -0.000000 0.000000 -0.000000 -0.004421 0.000000 0.000000 -0.000599 -0.000000 0.005289 0.000000 -0.000000 0.012826 -0.000000 0.000000 0.006190 0.000000 0.000000 -0.000000 0.000000 -0.000321 0.000000 -0.000000 -0.000000 0.000000 -0.000000 0.001499 -0.006629 0.000000 0.000000 0.000000 -0.000000 0.008737 -0.000000 0.006880 0.000000 -0.001851 -0.000000 -0.000000 0.000000 -0.007464 0.000000 0.010298 -0.000000 -0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.000540 0.000000 -0.006616 -0.000000 0.000000 -0.002927 -0.000000 0.000000 0.010352 0.000000 -0.003103 -0.000000 -0.007640 -0.000000 -0.000000 0.005302 0.000000 0.000000 -0.000000 -0.000000 -0.010181 0.000000 -0.001108 0.000000 0.000000 -0.000000 0.000000 0.000000 -0.000998 -0.009754 0.013562 0.000000 -0.000000 0.887510
    @@ -834,8 +834,8 @@ and finally we compute the overlap between all the MOs as
     
    -
    -

    1.3. Fortran

    +
    +

    1.3. Fortran

    Here is the same piece of code translated in Fortran @@ -1011,12 +1011,12 @@ Here is the same piece of code translated in Fortran

    -
    -

    2. Fortran

    +
    +

    2. Fortran

    -
    -

    2.1. Checking errors

    +
    +

    2.1. Checking errors

    All QMCkl functions return an error code. A convenient way to handle @@ -1025,7 +1025,7 @@ error in text format and exits the program.

    -
    subroutine qmckl_check_error(rc, message)
    +
    subroutine qmckl_check_error(rc, message)
       use qmckl
       implicit none
       integer(qmckl_exit_code), intent(in) :: rc
    @@ -1043,8 +1043,8 @@ error in text format and exits the program.
     
    -
    -

    2.2. Computing an atomic orbital on a grid

    +
    +

    2.2. Computing an atomic orbital on a grid

    The following program, in Fortran, computes the values of an atomic @@ -1263,7 +1263,7 @@ We finally print the value and Laplacian of the AO:

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_forces.html b/qmckl_forces.html new file mode 100644 index 0000000..3a1c333 --- /dev/null +++ b/qmckl_forces.html @@ -0,0 +1,4701 @@ + + + + + + + +Forces + + + + + + + + + + + + + +
    + UP + | + HOME +
    +

    Forces

    +
    +

    Table of Contents

    +
    + +
    +
    + +
    +

    1. Introduction

    +
    +

    +To calculate interatomic forces, a derivative (with respect to nuclei) of the values, gradient and Laplacian of the Jastrow and the molecular orbitals (MO) is required. +Furthermore, for the nonlocal pseudopotential, also the forces of the values of the single-electron move Jastrows are required. +

    +
    +
    + +
    +

    2. Context

    +
    +
    +
    +

    2.1. Data structure

    +
    +
    +
    typedef struct qmckl_forces_struct{
    +    double  * restrict forces_jastrow_en;
    +    uint64_t  forces_jastrow_en_date;
    +    double  * restrict forces_jastrow_en_g;
    +    uint64_t  forces_jastrow_en_g_date;
    +    double  * restrict forces_jastrow_en_l;
    +    uint64_t  forces_jastrow_en_l_date;
    +    double  * restrict forces_tmp_c;
    +    uint64_t  forces_tmp_c_date;
    +    double  * restrict forces_dtmp_c;
    +    uint64_t  forces_dtmp_c_date;
    +    double  * restrict forces_een_n;
    +    uint64_t  forces_een_n_date;
    +    double  * restrict forces_jastrow_een;
    +    uint64_t  forces_jastrow_een_date;
    +    double  * restrict forces_jastrow_een_g;
    +    uint64_t  forces_jastrow_een_g_date;
    +    double  * restrict forces_jastrow_een_l;
    +    uint64_t  forces_jastrow_een_l_date;
    +    double  * restrict forces_ao_value;
    +    uint64_t  forces_ao_value_date;
    +    uint64_t  forces_ao_value_maxsize;
    +    double  * restrict forces_mo_value;
    +    uint64_t  forces_mo_value_date;
    +    uint64_t  forces_mo_value_maxsize;
    +    double  * restrict forces_mo_g;
    +    uint64_t  forces_mo_g_date;
    +    double  * restrict forces_mo_l;
    +    uint64_t  forces_mo_l_date;
    +    double  * forces_jastrow_single_en;
    +    uint64_t  forces_jastrow_single_en_date;
    +    double  * forces_jastrow_single_een;
    +    uint64_t  forces_jastrow_single_een_date;
    +    double  * forces_delta_p;
    +    uint64_t  forces_delta_p_date;
    +} qmckl_forces_struct;
    +
    +
    +
    +
    +
    + +
    +

    3. Finite-difference function

    +
    +

    +We introduce here a general function to compute the derivatives of any quantity with respect to nuclear coordinates. +using finite-differences. +

    + +
    +
    +qmckl_exit_code qmckl_finite_difference_deriv_n(
    +    qmckl_context context,
    +    const double delta_x,
    +    function_callback get_function,
    +    double* const derivative_output,
    +    int64_t const size)
    +{
    +    // Finite difference coefficients for a 9-point stencil
    +    double coef[9] = { 1.0/280.0, -4.0/105.0, 1.0/5.0, -4.0/5.0, 0.0, 4.0/5.0, -1.0/5.0, 4.0/105.0, -1.0/280.0 };
    +
    +    qmckl_exit_code rc;
    +
    +    int64_t walk_num;
    +    rc = qmckl_get_electron_walk_num(context, &walk_num);
    +    if (rc != QMCKL_SUCCESS) {
    +      return rc;
    +    }
    +
    +    int64_t nucl_num;
    +    rc = qmckl_get_nucleus_num(context, &nucl_num);
    +    if (rc != QMCKL_SUCCESS) {
    +      return rc;
    +    }
    +
    +
    +    double* nucleus_coord = (double*) malloc(3 * nucl_num * sizeof(double));
    +    if (nucleus_coord == NULL) {
    +      return QMCKL_ALLOCATION_FAILED;
    +    }
    +    rc = qmckl_get_nucleus_coord (context, 'N', nucleus_coord, 3*nucl_num);
    +
    +
    +    double* temp_coord = (double*) malloc(3 * nucl_num * sizeof(double));
    +    if (temp_coord == NULL) {
    +      free(nucleus_coord);
    +      return QMCKL_ALLOCATION_FAILED;
    +    }
    +
    +    double* function_values = (double*) malloc(walk_num*size * sizeof(double));
    +    if (function_values == NULL) {
    +        free(nucleus_coord);
    +        free(temp_coord);
    +        return QMCKL_ALLOCATION_FAILED;
    +    }
    +
    +    memset(derivative_output, 0, nucl_num*3*walk_num*size*sizeof(double));
    +
    +    // Copy original coordinates
    +    for (int i = 0; i < 3 * nucl_num; i++) {
    +      temp_coord[i] = nucleus_coord[i];
    +    }
    +
    +    for (int64_t a = 0; a < nucl_num; a++) {
    +      for (int64_t k = 0; k < 3; k++) {
    +        for (int64_t m = -4; m <= 4; m++) {
    +
    +          // Apply finite difference displacement
    +          temp_coord[k+a*3] = nucleus_coord[k+3*a] + (double) m * delta_x;
    +
    +          // Update coordinates in the context
    +          rc = qmckl_set_nucleus_coord(context, 'N', temp_coord, 3*nucl_num);
    +          assert(rc == QMCKL_SUCCESS);
    +
    +          rc = qmckl_context_touch(context);
    +          assert(rc == QMCKL_SUCCESS);
    +
    +          rc = qmckl_single_touch(context);
    +          assert(rc == QMCKL_SUCCESS);
    +
    +          // Call the provided function
    +          rc = get_function(context, function_values, walk_num*size);
    +          assert(rc == QMCKL_SUCCESS);
    +
    +          // Accumulate derivative using finite-difference coefficients
    +          for (int64_t nw=0 ; nw<walk_num ; nw++) {
    +            int64_t shift = nucl_num*3*size*nw + size*(k + 3*a);
    +            for (int64_t i = 0; i < size; i++) {
    +              derivative_output[i+shift] += coef[m + 4] * function_values[nw*size+i];
    +            }
    +          }
    +        }
    +        temp_coord[k+a*3] = nucleus_coord[k+3*a];
    +      }
    +    }
    +
    +    // Reset coordinates in the context
    +    rc = qmckl_set_nucleus_coord(context, 'N', temp_coord, 3*nucl_num);
    +    assert(rc == QMCKL_SUCCESS);
    +
    +    rc = qmckl_context_touch(context);
    +    assert(rc == QMCKL_SUCCESS);
    +
    +    // Normalize by the step size
    +    for (int64_t i = 0; i < size*3*nucl_num*walk_num ; i++) {
    +      derivative_output[i] /= delta_x;
    +    }
    +
    +    free(nucleus_coord);
    +    free(temp_coord);
    +    free(function_values);
    +    return QMCKL_SUCCESS;
    +}
    +
    +
    +
    +
    +
    + +
    +

    4. Forces of the Jastrow function

    +
    +

    +For the forces of the Jastrow function, there is only a contribution from the electron-nucleus and electron-electron-nucleus Jastrow, since the electron-electron Jastrow does not depend on nuclear coordinates. +

    +
    + +
    +

    4.1. Electron-nucleus Jastrow

    +
    +
    +
    +

    4.1.1. Force of electron-nucleus Jastrow value

    +
    +

    +Calculates the force of the electron-nucleus Jastrow value. +The terms of the force of the electron-nucleus Jastrow value are identical to the gradient of this Jastrow, up to a minus sign. +\[ + \partial_{\alpha,m} J_{en} = -\sum_i \left( \frac{a_1 \partial_{i,m} \widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha} )^2} + \sum_{k=2}^{N_\text{aord}} a_k k \widetilde{R}_{i\alpha}^{k-1} \partial_{i,m} \widetilde{R}_{i\alpha} \right) +\] +

    +
    + +
    +
    4.1.1.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_en(qmckl_context context,
    +                                    double* const forces_jastrow_en,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_en (context, &
    +        forces_jastrow_en, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_en(size_max)
    +   end function qmckl_get_forces_jastrow_en
    +end interface
    +
    +
    +
    +
    + +
    +
    4.1.1.2. Compute
    +
    +
    + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus distances
    en_distance_rescaled_gldouble[walk_num][nucl_num][elec_num][4]inElectron-nucleus distance derivatives
    forces_jastrow_endouble[walk_num][nucl_num][3]outElectron-nucleus forces
    + +
    +
    function qmckl_compute_forces_jastrow_en_doc( &
    +     context, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, &
    +     en_distance_rescaled, en_distance_rescaled_gl, forces_jastrow_en) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled_gl(4, elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_en(3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, a, k, nw, ii
    +  double precision   :: x, x1, kf
    +  double precision   :: denom, invdenom, invdenom2, f
    +  double precision   :: dx(3)
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_7
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +    forces_jastrow_en(:,:,nw) = 0.0d0
    +    do a = 1, nucl_num
    +       do i = 1, elec_num
    +
    +          x = en_distance_rescaled(i,a,nw)
    +          if(abs(x) < 1.d-12) continue
    +
    +          denom = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x
    +          invdenom = 1.0d0 / denom
    +          invdenom2 = invdenom*invdenom
    +
    +          dx(1) = -en_distance_rescaled_gl(1,i,a,nw)
    +          dx(2) = -en_distance_rescaled_gl(2,i,a,nw)
    +          dx(3) = -en_distance_rescaled_gl(3,i,a,nw)
    +
    +          f = a_vector(1, type_nucl_vector(a)+1) * invdenom2
    +
    +          forces_jastrow_en(1,a,nw) = forces_jastrow_en(1,a,nw) + f * dx(1)
    +          forces_jastrow_en(2,a,nw) = forces_jastrow_en(2,a,nw) + f * dx(2)
    +          forces_jastrow_en(3,a,nw) = forces_jastrow_en(3,a,nw) + f * dx(3)
    +
    +
    +           kf = 2.d0
    +           x1 = x
    +           x = 1.d0
    +           do k=2, aord_num
    +              f = a_vector(k+1,type_nucl_vector(a)+1) * kf * x
    +              forces_jastrow_en(1,a,nw) = forces_jastrow_en(1,a,nw) + f * x1 * dx(1)
    +              forces_jastrow_en(2,a,nw) = forces_jastrow_en(2,a,nw) + f * x1 * dx(2)
    +              forces_jastrow_en(3,a,nw) = forces_jastrow_en(3,a,nw) + f * x1 * dx(3)
    +              x = x*x1
    +              kf = kf + 1.d0
    +           end do
    +
    +        end do
    +     end do
    +  end do
    +
    +
    +end function qmckl_compute_forces_jastrow_en_doc
    +
    +
    +
    +
    +
    + + +
    +

    4.1.2. Force of electron-nucleus Jastrow gradient

    +
    +

    +To avoid having to create new arrays for the Hessian of the rescaled distances, we compute parts of it manually in this routine. +

    +\begin{eqnarray} +\partial_{\alpha,m} \partial_{i,n} J_{en} & = \frac{a_1 \partial_{\alpha,m} \partial_{i,n} \widetilde{R}_{i\alpha} }{(1+a_2 \widetilde{R}_{i\alpha})^2} - 2 \frac{a_1 a_2 \partial_{\alpha,m} \widetilde{R}_{i\alpha} \partial_{i,n} \widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^3} + \sum_{k=2}^{N_\text{aord}} a_k k \left((k-1) \widetilde{R}_{i\alpha}^{k-2} \partial_{\alpha,m} \widetilde{R}_{i\alpha} \partial_{i,n} \widetilde{R}_{i\alpha} + \widetilde{R}_{i\alpha}^{k-1} \partial_{\alpha,m}\partial_{i,n} \widetilde{R}_{i\alpha} \right) \\ +& = -\frac{a_1 e^{-\kappa R_{i\alpha}}}{R_{i\alpha }(1+a_2 \widetilde{R}_{i\alpha})^2} + \frac{a_1 \partial_{i,m} \widetilde{R}_{i\alpha} \partial_{i,n} \widetilde{R}_{i\alpha} }{(1+a_2 \widetilde{R}_{i\alpha})^2}\left (\frac{e^{\kappa R_{i\alpha}}}{R_{i\alpha}} + \kappa e^{\kappa R_{i\alpha}} \right) + 2 \frac{a_1 a_2 \partial_{i,m} \widetilde{R}_{i\alpha} \partial_{i,n} \widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^3} \\ +&- \sum_{k=2}^{N_\text{aord}} a_k k \left((k-1) \widetilde{R}_{i\alpha}^{k-2} \partial_{\alpha,m} \widetilde{R}_{i\alpha} \partial_{i,n} \widetilde{R}_{i\alpha} - \widetilde{R}_{i\alpha}^{k-1} \partial_{i,m}\widetilde{R}_{i\alpha}\partial_{i,n} \widetilde{R}_{i\alpha} e^{\kappa R_{i\alpha}} (\kappa + \frac{1}{R_{i\alpha}}) + \delta_{n,m} e^{-\kappa R_{i\alpha}}\frac{1}{R_{i\alpha}} \right)\\ +\end{eqnarray} +
    + +
    +
    4.1.2.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_en_g(qmckl_context context,
    +                                    double* const forces_jastrow_en_g,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_en_g (context, &
    +        forces_jastrow_en_g, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_en_g(size_max)
    +   end function qmckl_get_forces_jastrow_en_g
    +end interface
    +
    +
    +
    +
    + +
    +
    4.1.2.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    rescale_factor_endouble[type_nucl_num]inRescale factor for electron-nucleus
    en_distancedouble[walk_num][elec_num][nucl_num]inElectron-nucleus distances
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus distances
    en_distance_rescaled_gldouble[walk_num][nucl_num][elec_num][4]inElectron-nucleus distance derivatives
    forces_jastrow_en_gdouble[walk_num][nucl_num][3][elec_num][3]outForce of electron-nucleus gradient
    + +
    +
    function qmckl_compute_forces_jastrow_en_g_doc( &
    +     context, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, rescale_factor_en, en_distance, &
    +     en_distance_rescaled, en_distance_rescaled_gl, forces_jastrow_en_g) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: rescale_factor_en(type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance(nucl_num,elec_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled_gl(4, elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_en_g(3,elec_num,3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, a, k, nw, ii, m,l
    +  double precision   :: x, x1, kf
    +  double precision   :: denom, invdenom, invdenom2, f, f2, expk, invdist
    +  double precision   :: dx(4)
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_7
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +    forces_jastrow_en_g(:,:,:,:,nw) = 0.0d0
    +    do a = 1, nucl_num
    +      do i = 1, elec_num
    +        expk = dexp(rescale_factor_en(type_nucl_vector(a)+1) * en_distance(a,i,nw))
    +        invdist = 1.d0 / en_distance(a,i,nw)
    +        x = en_distance_rescaled(i,a,nw)
    +        if(abs(x) < 1.d-12) continue
    +        denom = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x
    +        invdenom = 1.0d0 / denom
    +        invdenom2 = invdenom*invdenom
    +        f = a_vector(1, type_nucl_vector(a)+1) * invdenom2
    +
    +        do m = 1, 3
    +          dx(m) = en_distance_rescaled_gl(m,i,a,nw)
    +        end do
    +
    +        do m = 1, 3
    +          do l = 1,3
    +            if (m == l) then
    +              forces_jastrow_en_g(m,i,l,a,nw) = forces_jastrow_en_g(m,i,l,a,nw) - f  * invdist / expk
    +            end if
    +
    +            forces_jastrow_en_g(m,i,l,a,nw) = forces_jastrow_en_g(m,i,l,a,nw) + &
    +               f * dx(m) * dx(l) * expk * (invdist + rescale_factor_en(type_nucl_vector(a)+1))
    +            forces_jastrow_en_g(m,i,l,a,nw) = forces_jastrow_en_g(m,i,l,a,nw) + 2.d0 * f * invdenom * &
    +              a_vector(2, type_nucl_vector(a)+1) * dx(m) * dx(l)
    +          end do
    +        end do
    +
    +        kf = 2.d0
    +        x1 = x
    +        x = 1.d0
    +        do k=2, aord_num
    +          f = a_vector(k+1,type_nucl_vector(a)+1) * kf * x
    +          f2 = a_vector(k+1,type_nucl_vector(a)+1) * kf * x * (kf-1.d0)
    +
    +          do m = 1, 3
    +            do l = 1, 3
    +              if (m == l) then
    +                forces_jastrow_en_g(m,i,l,a,nw) = forces_jastrow_en_g(m,i,l,a,nw) - f * x1 * invdist / expk
    +              end if
    +              forces_jastrow_en_g(m,i,l,a,nw) = forces_jastrow_en_g(m,i,l,a,nw) - f2 * dx(m) * dx(l) &
    +                  + f * x1 * dx(m) * dx(l) * rescale_factor_en(type_nucl_vector(a)+1) * expk &
    +                  + f * x1 * dx(m) * dx(l) * invdist * expk
    +            end do
    +          end do
    +          x = x*x1
    +          kf = kf + 1.d0
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +
    +
    +end function qmckl_compute_forces_jastrow_en_g_doc
    +
    +
    +
    +
    +
    + +
    +

    4.1.3. Force of electron-nucleus Jastrow Laplacian

    +
    +

    +Calculates the force of the electron-nucleus Jastrow Laplacian. +To avoid having to calculate higher order derivatives of the rescaled distances elsewhere, the neccessery terms are calcuculated on the fly. +

    +\begin{eqnarray} +\partial_{\alpha,m} \nabla^2 J_{en} =& \sum_i \left(\partial_{\alpha,m}\frac{a_1 \nabla^2 \widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^2} - \partial_{\alpha,m} \frac{2a_1a_2 (\nabla\widetilde{R}_{i\alpha}\cdot \nabla \widetilde{R}_{i\alpha})}{(1+a_2\widetilde{R}_{i\alpha})^3} + \partial_{\alpha,m} \sum_{k=2}^{N_\text{aord}} a_k k \left( \widetilde{R}_{i\alpha}^{k-1} \nabla^2\widetilde{R}_{i\alpha} + (k-1)\widetilde{R}_{i\alpha}^{k-2} (\nabla \widetilde{R}_{i\alpha}\cdot \nabla \widetilde{R}_{i\alpha} ) \right) \right)\\ +=&\sum_i \left( \frac{a_1 \partial_{i,m} \widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^2}\left( \frac{2\kappa}{R_{i\alpha}} - \kappa^2 + \frac{2}{R^2_{i\alpha}}\right) + \frac{2a_1a_2\partial_{i,m}\widetilde{R}_{i\alpha}\nabla^2\widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^3} - \frac{4a_1a_2\kappa e^{-\kappa R_{i\alpha}}\partial_{i,m}\widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^3} - \frac{6 a_1 a_2^2 (\nabla \widetilde{R}_{i\alpha} \cdot \nabla \widetilde{R}_{i\alpha})\partial_{i,m}\widetilde{R}_{i\alpha}}{(1+a_2 \widetilde{R}_{i\alpha})^4} \right.\\ +&\left.+ \sum_{k=2}^{N_\text{aord}} a_k k \left( -(k-1) \widetilde{R}_{i\alpha}^{k-2}\partial_{i,m}\widetilde{R}_{i\alpha} \nabla^2\widetilde{R}_{i\alpha} + \widetilde{R}_{i\alpha}^{k-1}\partial_{i,m}\widetilde{R}_{i\alpha}\left(\frac{2\kappa}{R_{i\alpha}} - \kappa^2 + \frac{2}{R_{i\alpha}^2} \right) - (k-1)(k-2)\widetilde{R}_{i\alpha}^{k-3}\partial_{i,m}\widetilde{R}_{i\alpha}(\nabla\widetilde{R}_{i\alpha} \cdot \nabla \widetilde{R}_{i\alpha}) + 2\kappa(k-1)\widetilde{R}_{i\alpha}^{k-2} e^{-\kappa R_{i\alpha}} \partial_{i,m}\widetilde{R}_{i\alpha} \right) \right) +\end{eqnarray} +
    + +
    +
    4.1.3.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_en_l(qmckl_context context,
    +                                    double* const forces_jastrow_en_l,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_en_l (context, &
    +        forces_jastrow_en_l, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_en_l(size_max)
    +   end function qmckl_get_forces_jastrow_en_l
    +end interface
    +
    +
    +
    +
    + +
    +
    4.1.3.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    rescale_factor_endouble[type_nucl_num]inRescale factor for electron-nucleus
    en_distancedouble[walk_num][elec_num][nucl_num]inElectron-nucleus distances
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus distances
    en_distance_rescaled_gldouble[walk_num][nucl_num][elec_num][4]inElectron-nucleus distance derivatives
    forces_jastrow_en_ldouble[walk_num][nucl_num][3]outForces of electron-nucleus Laplacian
    + +
    +
    function qmckl_compute_forces_jastrow_en_l_doc( &
    +     context, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, rescale_factor_en, en_distance, &
    +     en_distance_rescaled, en_distance_rescaled_gl, forces_jastrow_en_l) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: rescale_factor_en(type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance(nucl_num, elec_num, walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled_gl(4, elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_en_l(3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, a, k, nw, ii, m,l
    +  double precision   :: x, x1, kf, grad_c2
    +  double precision   :: denom, invdenom, invdenom2, f, f2, expk, invdist
    +  double precision   :: dx(4)
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_7
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +    forces_jastrow_en_l(:,:,nw) = 0.0d0
    +    do a = 1, nucl_num
    +      do i = 1, elec_num
    +        expk = dexp(rescale_factor_en(type_nucl_vector(a)+1) * en_distance(a,i,nw))
    +        invdist = 1.d0 / en_distance(a,i,nw)
    +        x = en_distance_rescaled(i,a,nw)
    +        if(abs(x) < 1.d-12) continue
    +        denom = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x
    +        invdenom = 1.0d0 / denom
    +        invdenom2 = invdenom*invdenom
    +        f = a_vector(1, type_nucl_vector(a)+1) * invdenom2
    +
    +        do m = 1, 4
    +          dx(m) = en_distance_rescaled_gl(m,i,a,nw)
    +        end do
    +
    +        grad_c2 = dx(1)*dx(1) + dx(2)*dx(2) + dx(3)*dx(3)
    +
    +        do m = 1, 3
    +          forces_jastrow_en_l(m,a,nw) = forces_jastrow_en_l(m,a,nw) + f * dx(m) * &
    +            (rescale_factor_en(type_nucl_vector(a)+1) &
    +            * (2 *invdist - rescale_factor_en(type_nucl_vector(a)+1)) + 2*invdist*invdist)
    +          forces_jastrow_en_l(m,a,nw) = forces_jastrow_en_l(m,a,nw) + 2.d0 * f &
    +            * invdenom * a_vector(2, type_nucl_vector(a)+1) * dx(m) * dx(4)
    +          forces_jastrow_en_l(m,a,nw) = forces_jastrow_en_l(m,a,nw) - 4.d0 * f &
    +            * invdenom * a_vector(2, type_nucl_vector(a)+1) * rescale_factor_en(type_nucl_vector(a)+1) &
    +            * dx(m)/expk
    +          forces_jastrow_en_l(m,a,nw) = forces_jastrow_en_l(m,a,nw) - 6.d0 * f &
    +            * invdenom * invdenom * a_vector(2, type_nucl_vector(a)+1) * a_vector(2, type_nucl_vector(a)+1) &
    +            * grad_c2 * dx(m)
    +        end do
    +
    +
    +        kf = 2.d0
    +        x1 = x
    +        x = 1.d0
    +        do k=2, aord_num
    +          f = a_vector(k+1,type_nucl_vector(a)+1) * kf * x
    +          do m = 1, 3
    +            forces_jastrow_en_l(m,a,nw) = forces_jastrow_en_l(m,a,nw) &
    +              - f * dx(m) * dx(4) * (kf-1.d0) &
    +              - f / x1 * (kf-1.d0) * (kf-2.d0) * dx(m) /expk /expk &
    +              + f * x1 * rescale_factor_en(type_nucl_vector(a)+1) * dx(m) * dx(4) * expk &
    +              + f * x1 * 2 * dx(m) * invdist * invdist &
    +              + 2 * f * (kf-1.d0) * dx(m) * rescale_factor_en(type_nucl_vector(a)+1) / expk
    +          end do
    +          x = x*x1
    +          kf = kf + 1.d0
    +        end do
    +
    +      end do
    +    end do
    +  end do
    +
    +
    +
    +end function qmckl_compute_forces_jastrow_en_l_doc
    +
    +
    +
    +
    +
    + +
    +

    4.1.4. Force of single electron-nucleus Jastrow value

    +
    +

    +Calculate the force of the single-electron contribution ot the electron-nucleus Jastrow value. +\[ + \delta\partial_{\alpha,m} J_{en} = -\left( \frac{a_1 \partial_{i,m} \widetilde{R}_{i\alpha}^{\text{new}}}{(1+a_2 \widetilde{R}_{i\alpha}^{\text{new}} )^2} + \sum_{k=2}^{N_\text{aord}} a_k k {\widetilde{R}_{i\alpha}^{\text{new}}}^{k-1} \partial_{i,m} \widetilde{R}_{i\alpha}^{\text{new}} \right) + \left( \frac{a_1 \partial_{i,m} \widetilde{R}_{i\alpha}^{\text{old}}}{(1+a_2 \widetilde{R}_{i\alpha}^{\text{old}} )^2} + \sum_{k=2}^{N_\text{aord}} a_k k {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-1} \partial_{i,m} \widetilde{R}_{i\alpha}^{\text{old}} \right) +\] +

    + +

    +The function qmckl_set_single_point has to be called before this function to set the new electron position. +

    +
    + +
    +
    4.1.4.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_single_en(qmckl_context context,
    +                          double* const forces_jastrow_single_en,
    +                          const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.1.4.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    en_distance_rescaled_gldouble[walk_num][nucl_num][elec_num][4]inElectron-nucleus rescaled distance derivatives
    en_rescaled_singledouble[walk_num][nucl_num]inElectron-nucleus rescaled single distances
    en_rescaled_single_gldouble[walk_num][nucl_num][4]inElectron-nucleus rescaled single distance derivatives
    forces_jastrow_single_endouble[walk_num][nucl_num][3]outSingle electron-nucleus forces
    + +
    +
    function qmckl_compute_forces_jastrow_single_en_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, &
    +     en_distance_rescaled, en_distance_rescaled_gl, en_rescaled_single, en_rescaled_single_gl, forces_jastrow_single_en) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled_gl(4, elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_rescaled_single(nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_rescaled_single_gl(4, nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_single_en(3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, a, k, nw, ii, num
    +  double precision   :: x, x1, kf, x_old, x1_old
    +  double precision   :: denom, invdenom, invdenom2, f
    +  double precision   :: denom_old, invdenom_old, invdenom2_old, f_old
    +  double precision   :: dx(3), dx_old(3)
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_8
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +    forces_jastrow_single_en(:,:,nw) = 0.0d0
    +
    +    do a = 1, nucl_num
    +
    +      x_old = en_distance_rescaled(num,a,nw)
    +      x = en_rescaled_single(a,nw)
    +
    +
    +      denom = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x
    +      invdenom = 1.0d0 / denom
    +      invdenom2 = invdenom*invdenom
    +
    +      denom_old = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x_old
    +      invdenom_old = 1.0d0 / denom_old
    +      invdenom2_old = invdenom_old*invdenom_old
    +
    +      dx(1) = -en_rescaled_single_gl(1,a,nw)
    +      dx(2) = -en_rescaled_single_gl(2,a,nw)
    +      dx(3) = -en_rescaled_single_gl(3,a,nw)
    +
    +      dx_old(1) = -en_distance_rescaled_gl(1,num,a,nw)
    +      dx_old(2) = -en_distance_rescaled_gl(2,num,a,nw)
    +      dx_old(3) = -en_distance_rescaled_gl(3,num,a,nw)
    +
    +      f = a_vector(1, type_nucl_vector(a)+1) * invdenom2
    +
    +      f_old = a_vector(1, type_nucl_vector(a)+1) * invdenom2_old
    +
    +      forces_jastrow_single_en(1,a,nw) = forces_jastrow_single_en(1,a,nw) + f * dx(1) - f_old * dx_old(1)
    +      forces_jastrow_single_en(2,a,nw) = forces_jastrow_single_en(2,a,nw) + f * dx(2) - f_old * dx_old(2)
    +      forces_jastrow_single_en(3,a,nw) = forces_jastrow_single_en(3,a,nw) + f * dx(3) - f_old * dx_old(3)
    +
    +
    +      kf = 2.d0
    +      x1 = x
    +      x = 1.d0
    +      x1_old = x_old
    +      x_old = 1.d0
    +      do k=2, aord_num
    +        f = a_vector(k+1,type_nucl_vector(a)+1) * kf * x
    +        f_old = a_vector(k+1,type_nucl_vector(a)+1) * kf * x_old
    +        forces_jastrow_single_en(1,a,nw) = forces_jastrow_single_en(1,a,nw) + f * x1 * dx(1) - f_old * x1_old * dx_old(1)
    +        forces_jastrow_single_en(2,a,nw) = forces_jastrow_single_en(2,a,nw) + f * x1 * dx(2) - f_old * x1_old * dx_old(2)
    +        forces_jastrow_single_en(3,a,nw) = forces_jastrow_single_en(3,a,nw) + f * x1 * dx(3) - f_old * x1_old * dx_old(3)
    +        x = x*x1
    +        x_old = x_old*x1_old
    +        kf = kf + 1.d0
    +      end do
    +    end do
    +  end do
    +
    +end function qmckl_compute_forces_jastrow_single_en_doc
    +
    +
    +
    +
    +
    +
    + + +
    +

    4.2. Electron-electron-nucleus Jastrow

    +
    +
    +
    +

    4.2.1. Force of P matrix

    +
    +

    +Calculates the force of the P matrix. This is a required component to calculate the force on the 3-body Jastrow. +\[ +\partial_{\alpha,m} P_{i,\alpha,k,l} = \sum_j \widetilde{r}_{i,j,k} \partial_{\alpha,m}\widetilde{R}_{j,\alpha,l} = -\sum_j \widetilde{r}_{i,j,k} \partial_{j,m}\widetilde{R}_{j,\alpha,l} +\] +

    +
    + +
    +
    4.2.1.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_tmp_c(qmckl_context context,
    +                                    double* const forces_tmp_c,
    +                                    const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.2.1.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-nucleus rescaled
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled derivatives
    forces_tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]outForce on the P matrix
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_tmp_c( &
    +     context, walk_num, elec_num, nucl_num, cord_num,&
    +     een_rescaled_e, een_rescaled_n_gl, forces_tmp_c) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)          :: context
    +  integer (c_int64_t)   , intent(in), value   :: walk_num, elec_num, cord_num, nucl_num
    +  real    (c_double )   , intent(in)          :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)          :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(out)         :: forces_tmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +
    +  integer*8 :: nw, i
    +
    +  integer*8 :: l, m, k, a,j
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  do nw=1, walk_num
    +    do i=0, cord_num-1
    +      info = qmckl_dgemm(context,'N','N',elec_num*1_8,&
    +            nucl_num*(cord_num+1)*4_8, elec_num*1_8, -1.0d0,     &
    +            een_rescaled_e(1,1,i,nw),1_8*elec_num,              &
    +            een_rescaled_n_gl(1,1,1,0,nw),elec_num*1_8,         &
    +            0.0d0,                                              &
    +            forces_tmp_c(1,1,1,0,i,nw),1_8*elec_num)
    +    end do
    +  end do
    +
    +
    +
    +end function qmckl_compute_forces_tmp_c
    +
    +
    +
    +
    +
    + +
    +

    4.2.2. Force of derivative of the \(P\) matrix

    +
    +

    +Calculates the force of the derivative of the \(P\) matrix. +\[ +\partial_{\alpha,m} \partial_{i,n} P_{i,\alpha,k,l} = \sum_j \partial_{i,n} \widetilde{r}_{i,j,k} \partial_{\alpha,m}\widetilde{R}_{j,\alpha,l} = -\sum_j \partial_{i,n}\widetilde{r}_{i,j,k} \partial_{j,m}\widetilde{R}_{j,\alpha,l} +\] +

    +
    + +
    +
    4.2.2.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_dtmp_c(qmckl_context context,
    +                                    double* const forces_dtmp_c,
    +                                    const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.2.2.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_e_gldouble[walk_num][0:cord_num][elec_num][4][elec_num]inElectron-nucleus rescaled
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled derivatives
    forces_dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][4][elec_num]outForce of derivative of the P matrix
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_dtmp_c_doc( &
    +     context, walk_num, elec_num, nucl_num, cord_num,&
    +     een_rescaled_e_gl, een_rescaled_n_gl, forces_dtmp_c) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)          :: context
    +  integer (c_int64_t)   , intent(in), value   :: walk_num, elec_num, cord_num, nucl_num
    +  real    (c_double )   , intent(in)          :: een_rescaled_e_gl(elec_num, 4, elec_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)          :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(out)         :: forces_dtmp_c(elec_num, 4, nucl_num,4,0:cord_num, 0:cord_num-1, walk_num)
    +
    +  integer*8 :: nw, i, k
    +
    +  integer*8 :: l, m, a,j, kk
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  do nw = 1, walk_num
    +    do l = 0, cord_num-1
    +      do m = 1, cord_num
    +        do k = 1, 4
    +          do a = 1, nucl_num
    +            do kk = 1, 4
    +              do i = 1, elec_num
    +                forces_dtmp_c(i,kk,a,k,m,l,nw) = 0.d0
    +                do j = 1, elec_num
    +                  forces_dtmp_c(i,kk,a,k,m,l,nw) = forces_dtmp_c(i,kk,a,k,m,l,nw) - &
    +                        een_rescaled_e_gl(i,kk,j,l,nw) * een_rescaled_n_gl(j,k,a,m,nw)
    +                end do
    +              end do
    +            end do
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +end function qmckl_compute_forces_dtmp_c_doc
    +
    +
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_dtmp_c_hpc( &
    +     context, walk_num, elec_num, nucl_num, cord_num,&
    +     een_rescaled_e_gl, een_rescaled_n_gl, forces_dtmp_c) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)          :: context
    +  integer (c_int64_t)   , intent(in), value   :: walk_num, elec_num, cord_num, nucl_num
    +  real    (c_double )   , intent(in)          :: een_rescaled_e_gl(elec_num, 4, elec_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)          :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(out)         :: forces_dtmp_c(elec_num, 4, nucl_num,4,0:cord_num, 0:cord_num-1, walk_num)
    +
    +  integer*8 :: nw, i, k
    +  integer*8 :: l, m, a,j, kk
    +  double precision, allocatable :: tmp(:,:,:,:)
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  allocate(tmp(elec_num, 4, 4, nucl_num))
    +
    +  do nw = 1, walk_num
    +    do l = 0, cord_num-1
    +      do m = 1, cord_num
    +         info = qmckl_dgemm(context,'N','N', elec_num*4, 4*nucl_num, elec_num, -1.d0, &
    +              een_rescaled_e_gl(1,1,1,l,nw), elec_num*4_8, &
    +              een_rescaled_n_gl(1,1,1,m,nw), elec_num, 0.d0, &
    +              tmp, elec_num*4_8)
    +        do k = 1, 4
    +          do a = 1, nucl_num
    +             forces_dtmp_c(:,:,a,k,m,l,nw) = tmp(:,:,k,a)
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +  deallocate(tmp)
    +
    +end function qmckl_compute_forces_dtmp_c_hpc
    +
    +
    +
    +
    +
    + +
    +

    4.2.3. Force of electron-electron-nucleus Jastrow value

    +
    +

    +Calculates the force of the eleectron-electorn-nucleus Jastrow value. +\[ +\partial_{\alpha,m}J_{een} = \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \sum_{i=1}^{N_\text{elec}} \left(\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m}P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m}\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2}\right) +\] +

    +
    + +
    +
    4.2.3.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_een(qmckl_context context,
    +                                    double* const forces_jastrow_een,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_een (context, &
    +        forces_jastrow_een, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_een(size_max)
    +   end function qmckl_get_forces_jastrow_een
    +end interface
    +
    +
    +
    +
    + +
    +
    4.2.3.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled derivatives
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    forces_tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inForce of P matrix
    forces_jastrow_eendouble[walk_num][nucl_num][3]outForce of electron-electron-nucleus Jastrow value
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_jastrow_een( &
    +     context, walk_num, elec_num, nucl_num, cord_num,&
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +    een_rescaled_n, een_rescaled_n_gl, tmp_c, forces_tmp_c,forces_jastrow_een) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer (c_int64_t)   , intent(in), value  :: walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer (c_int64_t)   , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real    (c_double )   , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_tmp_c(elec_num,4, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(out) :: forces_jastrow_een(3, nucl_num, walk_num)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, ii
    +  double precision :: accu, accu2, cn
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  forces_jastrow_een = 0.d0
    +
    +  if (cord_num == 0) return
    +
    +  do nw =1, walk_num
    +    do n = 1, dim_c_vector
    +      l = lkpm_combined_index(n, 1)
    +      k = lkpm_combined_index(n, 2)
    +      p = lkpm_combined_index(n, 3)
    +      m = lkpm_combined_index(n, 4)
    +
    +      do a = 1, nucl_num
    +        cn = c_vector_full(a, n)
    +        if(cn == 0.d0) cycle
    +          do j = 1, elec_num
    +            do ii = 1, 3
    +              accu = een_rescaled_n(j,a,m,nw) * forces_tmp_c(j,ii,a,m+l,k,nw) &
    +                  - een_rescaled_n_gl(j,ii,a,m,nw) * tmp_c(j,a,m+l,k,nw)
    +
    +              forces_jastrow_een(ii, a, nw) = forces_jastrow_een(ii, a, nw) + accu * cn
    +            end do
    +          end do
    +      end do
    +    end do
    +  end do
    +
    +end function qmckl_compute_forces_jastrow_een
    +
    +
    +
    +
    +
    + +
    +

    4.2.4. Force of derivatives of electron-nucleus rescaled distance

    +
    +

    +Calculates the force of the derivatives of the electron-nucleus rescaled distance. +

    +\begin{eqnarray} +\partial_{\alpha,m}\partial_{i,n} \widetilde{R}_{i\alpha} =& \partial_{\alpha,m} \left( -\frac{r_{i,n} - R_{\alpha,n}}{R_{i\alpha}} \kappa l e^{-\kappa l R_{i\alpha}}\right)\\ +=& - \frac{(r_{i,n} - R_{\alpha,n})(r_{i,m} - R_{\alpha,m})}{R_{i\alpha}^3}l\kappa e^{-\kappa l R_{i\alpha}} - \frac{(r_{i,n} - R_{\alpha,n})(r_{i,m} - R_{\alpha,m})}{R_{i\alpha}^2} \kappa^2 l^2 e^{-\kappa l R_{i\alpha}} + \delta_{n,m} \frac{1}{r}\kappa l e^{-\kappa l R_{i\alpha}}\\ +\partial_{\alpha,m}\nabla^2 \widetilde{R}_{i\alpha} =& \partial_{\alpha,m} \left( \kappa l \left( \kappa l - \frac{2}{R_{i\alpha}}\right) e^{-\kappa l R_{i\alpha}}\right)\\ +=&-2\kappa l \frac{r_{i,m} - R_{\alpha,m}}{R_{i\alpha}^3}e^{-\kappa l R_{i\alpha}} + \kappa^2 l^2 \left(\kappa l - \frac{2}{R_{i\alpha}} \right) \frac{r_{i,m}-R_{\alpha,m}}{R_{i\alpha}} e^{-\kappa l R_{i\alpha}} +\end{eqnarray} +
    + +
    +
    4.2.4.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_een_rescaled_n_gl(qmckl_context context,
    +                                         double* const forces_een_n,
    +                                         const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.2.4.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of atoms
    type_nucl_numint64_tinNumber of atom types
    type_nucl_vectorint64_t[nucl_num]inTypes of atoms
    cord_numint64_tinOrder of polynomials
    rescale_factor_endouble[nucl_num]inFactor to rescale ee distances
    en_distancedouble[walk_num][elec_num][nucl_num]inElectron-nucleus distances
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivativies
    forces_een_ndouble[walk_num][0:cord_num][3][nucl_num][4][elec_num]outForce of electron-nucleus rescaled distances derivatives
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_een_rescaled_n_gl( &
    +     context, walk_num, elec_num, nucl_num, type_nucl_num, type_nucl_vector, &
    +     cord_num, rescale_factor_en, &
    +     en_distance, een_rescaled_n, een_rescaled_n_gl,forces_een_n) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer (c_int64_t)   , intent(in),value  :: walk_num, elec_num, nucl_num, type_nucl_num, cord_num
    +  integer (c_int64_t)   , intent(in)  :: type_nucl_vector(nucl_num)
    +  real    (c_double )   , intent(in)  :: rescale_factor_en(type_nucl_num)
    +  real    (c_double )   , intent(in)  :: en_distance(nucl_num,elec_num,walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n(elec_num,nucl_num,0:cord_num,walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n_gl(elec_num,4,nucl_num,0:cord_num,walk_num)
    +  real    (c_double )   , intent(out) :: forces_een_n(elec_num,4,nucl_num,3,0:cord_num,walk_num)
    +
    +  double precision                    :: x, ria_inv, kappa_l, temp
    +  integer*8                           :: i, a, k, l, nw, m, n
    +
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (cord_num < 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +
    +
    +  !forces_een_n = 0.0d0
    +  !do nw = 1, walk_num
    +  !  do l = 0, cord_num
    +  !    do a = 1, nucl_num
    +  !      kappa_l = dble(l)*rescale_factor_en(type_nucl_vector(a)+1)
    +  !      do i = 1, elec_num
    +  !        ria_inv = 1.0d0 / en_distance(a,i,nw)
    +  !        do n = 1, 3
    +  !          do m = 1, 3
    +  !            if (m == n) then
    +  !              forces_een_n(i,m,a,n,l,nw) = forces_een_n(i,m,a,n,l,nw) + &
    +  !                    kappa_l*een_rescaled_n(i,a,l,nw) * ria_inv
    +  !            end if
    +  !            temp = een_rescaled_n_gl(i,m,a,l,nw) * een_rescaled_n_gl(i,n,a,l,nw) / een_rescaled_n(i,a,l,nw)
    +  !            forces_een_n(i,m,a,n,l,nw) = forces_een_n(i,m,a,n,l,nw) - &
    +  !               temp * ria_inv / kappa_l - temp
    +  !          end do
    +  !          forces_een_n(i,4,a,n,l,nw) = forces_een_n(i,4,a,n,l,nw) + &
    +  !            (2.0d0 * ria_inv * ria_inv &
    +  !            - een_rescaled_n_gl(i,4,a,l,nw)/een_rescaled_n(i,a,l,nw)) * &
    +  !            een_rescaled_n_gl(i,n,a,l,nw)
    +  !        end do
    +  !      end do
    +  !    end do
    +  !  end do
    +  !end do
    +
    +
    +    forces_een_n = 0.0d0
    +    do nw = 1, walk_num
    +    do i = 1, elec_num
    +      do a = 1, nucl_num
    +        do l = 0, cord_num
    +          kappa_l = dble(l)*rescale_factor_en(type_nucl_vector(a)+1)
    +          do m = 1, 4
    +            do n = 1, 3
    +              if (l == 0) then
    +                forces_een_n(i,m,a,n,l,nw) = 0.0d0
    +              else
    +                if (m == n) then
    +                  forces_een_n(i,m,a,n,l,nw) = forces_een_n(i,m,a,n,l,nw) + &
    +                       kappa_l*een_rescaled_n(i,a,l,nw)/en_distance(a,i,nw)
    +                end if
    +                if (m < 4) then
    +                forces_een_n(i,m,a,n,l,nw) = forces_een_n(i,m,a,n,l,nw) - &
    +                  een_rescaled_n_gl(i,m,a,l,nw) * een_rescaled_n_gl(i,n,a,l,nw) / &
    +                  (kappa_l*een_rescaled_n(i,a,l,nw)*en_distance(a,i,nw)) - &
    +                   een_rescaled_n_gl(i,m,a,l,nw) * &
    +                   een_rescaled_n_gl(i,n,a,l,nw)/een_rescaled_n(i,a,l,nw)
    +                else
    +                forces_een_n(i,m,a,n,l,nw) = forces_een_n(i,m,a,n,l,nw) + &
    +                  2.0d0 * een_rescaled_n_gl(i,n,a,l,nw) / &
    +                  (en_distance(a,i,nw)*en_distance(a,i,nw)) - &
    +                  een_rescaled_n_gl(i,m,a,l,nw) * &
    +                  een_rescaled_n_gl(i,n,a,l,nw)/een_rescaled_n(i,a,l,nw)
    +                end if
    +
    +              end if
    +            end do
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +
    +end function qmckl_compute_forces_een_rescaled_n_gl
    +
    +
    +
    +
    +
    + +
    +

    4.2.5. Force of electron-electron-nucleus Jastrow gradient

    +
    +

    +Calculates the force of the electron-electron-nucleus Jastrow gradient (and not the Laplacian). +

    +\begin{eqnarray} +\partial_{\alpha,m} \partial_{i,n}J_{een} =& \partial_{\alpha,m} \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left(\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{i,n} P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{i,n} P_{i\alpha,k,(p-k+l)/2} \right)\\ +=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left(\partial_{\alpha,m}\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m}\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} + \partial_{\alpha,m}\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{i,n} P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m}\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{i,n} P_{i\alpha,k,(p-k+l)/2} \right.\\ + &+ \left.\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m}P_{i\alpha,k,(p-k-l)/2} + \partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m}P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m}\partial_{i,n} P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m}\partial_{i,n} P_{i\alpha,k,(p-k+l)/2}\right)\\ +=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left(\partial_{\alpha,m}\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m}\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} - \partial_{i,m}\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{i,n} P_{i\alpha,k,(p-k-l)/2} - \partial_{i,m}\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{i,n} P_{i\alpha,k,(p-k+l)/2} \right.\\ + &+ \left.\partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m}P_{i\alpha,k,(p-k-l)/2} + \partial_{i,n}\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m}P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m}\partial_{i,n} P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m}\partial_{i,n} P_{i\alpha,k,(p-k+l)/2}\right)\\ +\end{eqnarray} +
    + +
    +
    4.2.5.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_een_g(qmckl_context context,
    +                                     double* const forces_jastrow_een_g,
    +                                     const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_een_g (context, &
    +        forces_jastrow_een_g, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_een_g(size_max)
    +   end function qmckl_get_forces_jastrow_een_g
    +end interface
    +
    +
    +
    +
    + +
    +
    4.2.5.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    en_distancedouble[elec_num][nucl_num]inElectron-nucleus distance
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inDerivative of P matrix
    forces_tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inForce of P matrix
    forces_dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][4][elec_num]inForce of derivative of P matrix
    forces_een_ndouble[walk_num][0:cord_num][3][nucl_num][4][elec_num]inForce of derivatives of electron-nucleus rescaled factor
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled factor
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inDerivative of electron-nucleus rescaled factor
    forces_jastrow_een_gdouble[walk_num][3][nucl_num][3][elec_num]outForce of the electron-electron-nucleus Jastrow gradient
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_jastrow_een_g( &
    +     context, walk_num, elec_num, nucl_num, &
    +     cord_num, dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     en_distance, tmp_c, dtmp_c, forces_tmp_c, forces_dtmp_c, forces_een_n, een_rescaled_n, &
    +    een_rescaled_n_gl, forces_jastrow_een_g)&
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer (c_int64_t)   , intent(in),value  :: walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer (c_int64_t)   , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real    (c_double )   , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real    (c_double )   , intent(in)  :: en_distance(nucl_num, elec_num)
    +  real    (c_double )   , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: dtmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_tmp_c(elec_num, 4,nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_dtmp_c(elec_num, 4, nucl_num,4,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_een_n(elec_num, 4, nucl_num, 3, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(out) :: forces_jastrow_een_g(elec_num,3,nucl_num,3,walk_num)
    +
    +  integer*8 :: i, a, j, l, k, m, n, nw, ii, jj
    +  double precision :: accu, accu2, cn
    +
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +
    +  if (cord_num == 0) return
    +  forces_jastrow_een_g = 0.0d0
    +  do nw =1, walk_num
    +     do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do a = 1, nucl_num
    +           cn = c_vector_full(a, n)
    +           if(cn == 0.d0) cycle
    +
    +           do ii = 1, 3
    +              do i = 1, elec_num
    +                do jj = 1, 3
    +                forces_jastrow_een_g(i, ii, a, jj, nw) = forces_jastrow_een_g(i, ii, a, jj, nw) + (&
    +                    tmp_c(i,a,              m,  k,nw) *  forces_een_n(i,ii,a,jj  ,m+l,nw)  &
    +                  + forces_tmp_c(i,jj,a,    m,  k,nw) *  een_rescaled_n_gl(i,ii,a,m+l,nw)  &
    +                  + tmp_c(i,a,              m+l,k,nw) *  forces_een_n(i,ii,a,jj,  m,  nw)  &
    +                  + forces_tmp_c(i,jj,a,    m+l,k,nw) *  een_rescaled_n_gl(i,ii,a,m,  nw)  &
    +                  - dtmp_c(i,ii,a,          m,  k,nw) *  een_rescaled_n_gl(i,jj,a,m+l,nw)  &
    +                  + forces_dtmp_c(i,ii,a,jj,m,  k,nw) *  een_rescaled_n(i,a,      m+l,nw)  &
    +                  - dtmp_c(i,ii,a,          m+l,k,nw) *  een_rescaled_n_gl(i,jj,a,m,  nw)  &
    +                  + forces_dtmp_c(i,ii,a,jj,m+l,k,nw) *  een_rescaled_n(i,a,      m,  nw)  &
    +                 ) * cn
    +
    +                end do
    +              end do
    +           end do
    +
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_forces_jastrow_een_g
    +
    +
    +
    +
    +
    + +
    +

    4.2.6. Force of electron-electron-nucleus Jastrow Laplacian

    +
    +

    +Calculates the force of the electron-electron-nucleus Jastrow Laplacian. +

    +\begin{eqnarray} +\partial_{\alpha,m} \nabla^2 J_{een} &=& \partial_{\alpha,m} \sum_{i=1}^{N_\text{elec}}\sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left(\nabla^2\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \nabla^2\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \nabla^2 P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \nabla^2 P_{i\alpha,k,(p-k+l)/2} \right.\\ +&&+ \left. 2 \nabla \widetilde{R}_{i\alpha}^{(p-k+l)/2} \cdot \nabla P_{i\alpha,k,(p-k-l)/2} + 2 \nabla \widetilde{R}_{i\alpha}^{(p-k-l)/2} \cdot \nabla P_{i\alpha,k,(p-k+l)/2} \right)\\ +&=& \sum_{i=1}^{N_\text{elec}}\sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left( \partial_{\alpha,m} \nabla^2\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m} \nabla^2\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} + \partial_{\alpha,m} \widetilde{R}_{i\alpha}^{(p-k+l)/2} \nabla^2 P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m} \widetilde{R}_{i\alpha}^{(p-k-l)/2} \nabla^2 P_{i\alpha,k,(p-k+l)/2} \right.\\ +&&+\nabla^2\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m} P_{i\alpha,k,(p-k-l)/2} + \nabla^2\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m} P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m} \nabla^2 P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m} \nabla^2 P_{i\alpha,k,(p-k+l)/2} \\ +&&+ \left. 2 \partial_{\alpha,m} \nabla \widetilde{R}_{i\alpha}^{(p-k+l)/2} \cdot \nabla P_{i\alpha,k,(p-k-l)/2} + 2 \partial_{\alpha,m} \nabla \widetilde{R}_{i\alpha}^{(p-k-l)/2} \cdot \nabla P_{i\alpha,k,(p-k+l)/2} + 2 \nabla \widetilde{R}_{i\alpha}^{(p-k+l)/2} \cdot \partial_{\alpha,m} \nabla P_{i\alpha,k,(p-k-l)/2} + 2 \nabla \widetilde{R}_{i\alpha}^{(p-k-l)/2} \cdot \partial_{\alpha,m} \nabla P_{i\alpha,k,(p-k+l)/2} \right)\\ +&=& \sum_{i=1}^{N_\text{elec}}\sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left( \partial_{\alpha,m} \nabla^2\widetilde{R}_{i\alpha}^{(p-k+l)/2} P_{i\alpha,k,(p-k-l)/2} + \partial_{\alpha,m} \nabla^2\widetilde{R}_{i\alpha}^{(p-k-l)/2} P_{i\alpha,k,(p-k+l)/2} - \partial_{i,m} \widetilde{R}_{i\alpha}^{(p-k+l)/2} \nabla^2 P_{i\alpha,k,(p-k-l)/2} - \partial_{i,m} \widetilde{R}_{i\alpha}^{(p-k-l)/2} \nabla^2 P_{i\alpha,k,(p-k+l)/2} \right.\\ +&&+\nabla^2\widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m} P_{i\alpha,k,(p-k-l)/2} + \nabla^2\widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m} P_{i\alpha,k,(p-k+l)/2} + \widetilde{R}_{i\alpha}^{(p-k+l)/2} \partial_{\alpha,m} \nabla^2 P_{i\alpha,k,(p-k-l)/2} + \widetilde{R}_{i\alpha}^{(p-k-l)/2} \partial_{\alpha,m} \nabla^2 P_{i\alpha,k,(p-k+l)/2} \\ +&&+ \left. 2 \partial_{\alpha,m} \nabla \widetilde{R}_{i\alpha}^{(p-k+l)/2} \cdot \nabla P_{i\alpha,k,(p-k-l)/2} + 2 \partial_{\alpha,m} \nabla \widetilde{R}_{i\alpha}^{(p-k-l)/2} \cdot \nabla P_{i\alpha,k,(p-k+l)/2} + 2 \nabla \widetilde{R}_{i\alpha}^{(p-k+l)/2} \cdot \partial_{\alpha,m} \nabla P_{i\alpha,k,(p-k-l)/2} + 2 \nabla \widetilde{R}_{i\alpha}^{(p-k-l)/2} \cdot \partial_{\alpha,m} \nabla P_{i\alpha,k,(p-k+l)/2} \right) +\end{eqnarray} +
    + +
    +
    4.2.6.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_een_l(qmckl_context context,
    +                                     double* const forces_jastrow_een_l,
    +                                     const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_forces_jastrow_een_l (context, &
    +        forces_jastrow_een_l, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: forces_jastrow_een_l(size_max)
    +   end function qmckl_get_forces_jastrow_een_l
    +end interface
    +
    +
    +
    +
    + +
    +
    4.2.6.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    en_distancedouble[elec_num][nucl_num]inElectron-nucleus distance
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inDerivative of P matrix
    forces_tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inForce of P matrix
    forces_dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][4][elec_num]inForce of derivative of P matrix
    forces_een_ndouble[walk_num][0:cord_num][3][nucl_num][4][elec_num]inForce of derivative of electron-nucleus rescaled factor
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled factor
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inDerivative of electron-nucleus rescaled factor
    forces_jastrow_een_ldouble[walk_num][3][nucl_num]outForce of electron-electron-nucleus Jastrow Laplacian
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_jastrow_een_l( &
    +     context, walk_num, elec_num, nucl_num, &
    +     cord_num, dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     en_distance, tmp_c, dtmp_c, forces_tmp_c, forces_dtmp_c, forces_een_n, een_rescaled_n, &
    +      een_rescaled_n_gl, forces_jastrow_een_l)&
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer (c_int64_t)   , intent(in),value  :: walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer (c_int64_t)   , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real    (c_double )   , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real    (c_double )   , intent(in)  :: en_distance(nucl_num, elec_num)
    +  real    (c_double )   , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: dtmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_tmp_c(elec_num, 4,nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_dtmp_c(elec_num, 4, nucl_num,4,0:cord_num, 0:cord_num-1,  walk_num)
    +  real    (c_double )   , intent(in)  :: forces_een_n(elec_num, 4, nucl_num, 3, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double )   , intent(out) :: forces_jastrow_een_l(nucl_num,3,walk_num)
    +
    +  integer*8 :: i, a, j, l, k, m, n, nw, ii, jj
    +  double precision :: accu, accu2, cn
    +
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_2
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_5
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +
    +  if (cord_num == 0) return
    +  forces_jastrow_een_l = 0.0d0
    +  do nw =1, walk_num
    +     do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do a = 1, nucl_num
    +           cn = c_vector_full(a, n)
    +           if(cn == 0.d0) cycle
    +
    +           do ii = 1, 3
    +              do i = 1, elec_num
    +                forces_jastrow_een_l(a, ii, nw) = forces_jastrow_een_l(a, ii, nw) + (&
    +                     tmp_c(i,a,             m,  k,nw) *  forces_een_n(i,4,a,ii  ,m+l,nw) &
    +                   + forces_tmp_c(i,ii,a,   m,  k,nw) *  een_rescaled_n_gl(i,4,a,m+l,nw) &
    +                   + tmp_c(i,a,             m+l,k,nw) *  forces_een_n(i,4,a,ii,  m,  nw) &
    +                   + forces_tmp_c(i,ii,a,   m+l,k,nw) *  een_rescaled_n_gl(i,4,a,m,  nw) &
    +                   - dtmp_c(i,4,a,          m,  k,nw) *  een_rescaled_n_gl(i,ii,a,m+l,nw) &
    +                   + forces_dtmp_c(i,4,a,ii,m,  k,nw) *  een_rescaled_n(i,a,      m+l,nw) &
    +                   - dtmp_c(i,4,a,          m+l,k,nw) *  een_rescaled_n_gl(i,ii,a,m,  nw) &
    +                   + forces_dtmp_c(i,4,a,ii,m+l,k,nw) *  een_rescaled_n(i,a,      m,  nw) &
    +                 )   * cn
    +              end do
    +           end do
    +
    +           cn = cn + cn
    +            do ii = 1, 3
    +              do i = 1, elec_num
    +                do jj = 1, 3
    +                  forces_jastrow_een_l(a, ii, nw) = forces_jastrow_een_l(a, ii, nw) + (&
    +                      dtmp_c(i,jj,a,m, k,nw) * forces_een_n(i,jj,a,ii ,m+l,nw) + &
    +                      dtmp_c(i,jj,a,m+l, k,nw) * forces_een_n(i,jj,a,ii ,m,nw) + &
    +                      forces_dtmp_c(i,jj,a,ii,m, k,nw) * een_rescaled_n_gl(i,jj,a,m+l,nw) + &
    +                      forces_dtmp_c(i,jj,a,ii,m+l, k,nw) * een_rescaled_n_gl(i,jj,a,m,nw) &
    +                    ) * cn
    +                end do
    +              end do
    +            end do
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_forces_jastrow_een_l
    +
    +
    +
    +
    +
    + +
    +

    4.2.7. Force of \(\delta P\) matrix

    +
    +

    +Calculates the force of the \(\delta P\) matrix, required for force in a single-electron move. Here, the \(r^\text{new}\) and \(R^\text{new}\) are the new electron and nucleus positions of the electron that is being moved. +

    +\begin{eqnarray*} +\partial_{\alpha,m}\delta P_{i,\alpha,k,l} &=& \partial_{\alpha,m} \left(\sum_{j=1}^{N_\text{elec}} \left( \delta \widetilde{r}_{ij}^k \widetilde{R}_{j\alpha}^l \delta_{i,\text{num}} \right) ++ \widetilde{r}_{i,\text{num}}^k \delta \widetilde{R}_{\text{num},\alpha}^l + \delta \widetilde{r}_{i,\text{num}}^k \left( \widetilde{R}_{\text{num},\alpha}^l ++ \delta \widetilde{R}_{\text{num},\alpha}^l \right)\right) \\ +&=& \partial_{\alpha,m} \left(\sum_{j=1}^{N_\text{elec}} \left( \delta \widetilde{r}_{ij}^k \widetilde{R}_{j\alpha}^l \delta_{i,\text{num}} \right) ++ \widetilde{r}_{i,\text{num}}^k \widetilde{R}_{\text{num},\alpha}^l + {\widetilde{r}_{i,\text{num}}^{\text{new}}}^k {\widetilde{R}_{\text{num},\alpha}^{\text{new}}}^l \right) \\ +&=& \left(\sum_{j=1}^{N_\text{elec}} \left( \delta \widetilde{r}_{ij}^k \partial_{\alpha,m} \widetilde{R}_{j\alpha}^l \delta_{i,\text{num}} \right) ++ \widetilde{r}_{i,\text{num}}^k \partial_{\alpha,m}\widetilde{R}_{\text{num},\alpha}^l + {\widetilde{r}_{i,\text{num}}^{\text{new}}}^k \partial_{\alpha,m}{\widetilde{R}_{\text{num},\alpha}^{\text{new}}}^l \right) \\ +&=& \left(\sum_{j=1}^{N_\text{elec}} \left( -\delta \widetilde{r}_{ij}^k \partial_{i,m} \widetilde{R}_{j\alpha}^l \delta_{i,\text{num}} \right) +- \widetilde{r}_{i,\text{num}}^k \partial_{i,m}\widetilde{R}_{\text{num},\alpha}^l - {\widetilde{r}_{i,\text{num}}^{\text{new}}}^k \partial_{i,m}{\widetilde{R}_{\text{num},\alpha}^{\text{new}}}^l \right) \\ +\end{eqnarray*} + +

    +The function qmckl_set_single_point has to be called before this function to set the new electron position. +

    +
    +
    +
    4.2.7.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_delta_p(qmckl_context context,
    +                                 double* const forces_delta_p,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.2.7.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-electron rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    forces_delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][3][elec_num]outForce of \(\delta P\) matrix
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_forces_jastrow_delta_p_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     een_rescaled_n, een_rescaled_e, een_rescaled_single_n, een_rescaled_single_e, &
    +     een_rescaled_n_gl, een_rescaled_single_n_gl, forces_delta_p) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out)  :: forces_delta_p(elec_num,3,nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: tmp1, tmp2
    +  double precision        :: delta_e(elec_num)
    +
    +
    +
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num
    +  double precision :: tmp, accu
    +  integer*8        :: LDA, LDB, LDC
    +
    +  num = num_in + 1_8
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +  if (cord_num == 0) then
    +     forces_delta_p = 0.d0
    +     return
    +  endif
    +
    +
    +  do nw=1, walk_num
    +    do m=0, cord_num-1
    +
    +      do j = 1, elec_num
    +        delta_e(j) =  een_rescaled_e(j,num,m,nw) - een_rescaled_single_e(j,m,nw)
    +      end do
    +
    +      do l=1, cord_num
    +        do a = 1, nucl_num
    +          do k = 1, 3
    +            tmp1 = een_rescaled_n_gl(num, k, a, l, nw)
    +            tmp2 = een_rescaled_single_n_gl(k,a,l,nw)
    +            accu = 0.d0
    +            do j = 1, elec_num
    +              forces_delta_p(j,k,a,l,m,nw) =  een_rescaled_e(j,num,m,nw) * tmp1 - &
    +                een_rescaled_single_e(j,m,nw)  * tmp2
    +
    +              accu = accu + delta_e(j) * een_rescaled_n_gl(j,k,a,l,nw)
    +            end do
    +            forces_delta_p(num,k,a,l,m,nw) = forces_delta_p(num,k,a,l,m,nw) + accu
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +end function qmckl_compute_forces_jastrow_delta_p_doc
    +
    +
    + +
    +
    qmckl_exit_code
    +qmckl_compute_forces_jastrow_delta_p_hpc (const qmckl_context context,
    +                                          const int64_t num,
    +                                          const int64_t walk_num,
    +                                          const int64_t elec_num,
    +                                          const int64_t nucl_num,
    +                                          const int64_t cord_num,
    +                                          const double* een_rescaled_n,
    +                                          const double* een_rescaled_e,
    +                                          const double* een_rescaled_single_n,
    +                                          const double* een_rescaled_single_e,
    +                                          const double* een_rescaled_n_gl,
    +                                          const double* een_rescaled_single_n_gl,
    +                                          double* const forces_delta_p )
    +{ 
    +  if (context == QMCKL_NULL_CONTEXT)    return QMCKL_INVALID_CONTEXT;
    +  if (num < 0)                          return QMCKL_INVALID_ARG_2;
    +  if (walk_num <= 0)                    return QMCKL_INVALID_ARG_3;
    +  if (elec_num <= 0)                    return QMCKL_INVALID_ARG_4;
    +  if (nucl_num <= 0)                    return QMCKL_INVALID_ARG_5;
    +  if (cord_num <  0)                    return QMCKL_INVALID_ARG_6;
    +  if (een_rescaled_n == NULL)           return QMCKL_INVALID_ARG_7;
    +  if (een_rescaled_e == NULL)           return QMCKL_INVALID_ARG_8;
    +  if (een_rescaled_single_n == NULL)    return QMCKL_INVALID_ARG_9;
    +  if (een_rescaled_single_e == NULL)    return QMCKL_INVALID_ARG_10;
    +  if (een_rescaled_n_gl == NULL)        return QMCKL_INVALID_ARG_11;
    +  if (een_rescaled_single_n_gl == NULL) return QMCKL_INVALID_ARG_12;
    +
    +  if (cord_num == 0) {
    +    const size_t dim = elec_num*3*nucl_num*(cord_num+1)*cord_num;
    +    #pragma omp parallel for 
    +    for (int64_t nw = 0; nw < walk_num; ++nw) {
    +      memset(&forces_delta_p[dim*nw],0,dim*sizeof(double));
    +    }
    +    return QMCKL_SUCCESS;
    +  }
    +
    +  #pragma omp parallel for 
    +  for (int64_t nw = 0; nw < walk_num; ++nw) {
    +
    +    for (int64_t m = 0; m <= cord_num-1; ++m) {
    +
    +      double delta_e[elec_num];
    +      const double* een_rescaled_e_ = &een_rescaled_e[elec_num*(num+elec_num*(m+(cord_num+1)*nw))];
    +      const double* een_rescaled_single_e_ = &een_rescaled_single_e[elec_num*(m+(cord_num+1)*nw)];
    +      for (int64_t j = 0; j < elec_num; ++j) {
    +        delta_e[j] = een_rescaled_e_[j] - een_rescaled_single_e_[j];
    +      }
    +
    +      for (int64_t l = 1; l <= cord_num; ++l) {
    +        for (int64_t a = 0; a < nucl_num; ++a) {
    +          for (int64_t k = 0; k < 3; ++k) {
    +            const double* een_rescaled_n_gl_ = &een_rescaled_n_gl[elec_num*(k+4*(a+nucl_num*(l+(cord_num+1)*nw)))];
    +            const double tmp1 = een_rescaled_n_gl_[num];
    +            const double tmp2 = een_rescaled_single_n_gl[k+4*(a+nucl_num*(l+(cord_num+1)*nw))];
    +
    +            double* forces_delta_p_ = &forces_delta_p[elec_num*(k+3*(a+nucl_num*(l+(cord_num+1)*(m+cord_num*nw))))];
    +            double accu = 0.0;
    +            #pragma omp simd reduction(+:accu)
    +            for (int64_t j = 0; j < elec_num; ++j) {
    +              forces_delta_p_[j] = een_rescaled_e_[j] * tmp1 - een_rescaled_single_e_[j] * tmp2;
    +              accu += delta_e[j] * een_rescaled_n_gl_[j];
    +            }
    +            forces_delta_p_[num] += accu;
    +          }
    +        }
    +      }
    +    }
    +  }
    +
    +  return QMCKL_SUCCESS;
    +}
    +
    +
    +
    +
    +
    + +
    +

    4.2.8. Force of single electron-electron-nucleus Jastrow value

    +
    +

    +Computes the single-electron contribution to the electron-electron-nucleus Jastrow value force. +

    + +\begin{eqnarray*} +\partial_{\alpha,m} \delta J_{een} &=& \partial_{\alpha,m} \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left( +\sum_{i=1}^{N_\text{elec}} \left( \widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(P_{\text{num},\alpha,k,(p-k+l)/2} + \delta P_{\text{num},\alpha,k,(p-k+l)/2} \right)\right)\\ +&=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left( +\sum_{i=1}^{N_\text{elec}} \left( \partial_{\alpha,m}\widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} + \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{\alpha,m}\delta P_{i,\alpha,k,(p-k+l)/2} \right) \right.\\ +&&\left. + \partial_{\alpha,m}\delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(P_{\text{num},\alpha,k,(p-k+l)/2} + \delta P_{\text{num},\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(\partial_{\alpha,m}P_{\text{num},\alpha,k,(p-k+l)/2} + \partial_{\alpha,m}\delta P_{\text{num},\alpha,k,(p-k+l)/2} \right)\right)\\ +&=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}} c_{l,k,p,\alpha} \left( +\sum_{i=1}^{N_\text{elec}} \left( -\partial_{i,m}\widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} + \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{\alpha,m}\delta P_{i,\alpha,k,(p-k+l)/2} \right) \right.\\ +&&\left. - \partial_{i,m}\delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(P_{\text{num},\alpha,k,(p-k+l)/2} + \delta P_{\text{num},\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(\partial_{\alpha,m}P_{\text{num},\alpha,k,(p-k+l)/2} + \partial_{\alpha,m}\delta P_{\text{num},\alpha,k,(p-k+l)/2} \right)\right)\\ +\end{eqnarray*} + +

    +The function qmckl_set_single_point has to be called before this function to set the new electron position. +

    +
    +
    +
    4.2.8.1. Get
    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_jastrow_single_een(qmckl_context context,
    +                          double* const forces_jastrow_single_een,
    +                          const int64_t size_max);
    +
    +
    +
    +
    + +
    +
    4.2.8.2. Compute
    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]in\(\delta P\) matrix
    forces_delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][3][elec_num]inForce of $δ P$matrix
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    forces_tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inForce of P matrix
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    forces_jastrow_single_eendouble[walk_num][nucl_num][3]outSingle electron–electron-nucleus Jastrow forces
    + +
    +
    function qmckl_compute_forces_jastrow_single_een_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num, &
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     delta_p, forces_delta_p, tmp_c, forces_tmp_c, &
    +     een_rescaled_n, een_rescaled_single_n, een_rescaled_n_gl, een_rescaled_single_n_gl, forces_jastrow_single_een) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: dim_c_vector
    +  integer (c_int64_t) , intent(in)  , value :: cord_num
    +  integer(c_int64_t)   , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real(c_double)      , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real    (c_double ) , intent(in)          :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: forces_delta_p(elec_num, 3, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: forces_tmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_single_een(3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  double precision        :: een_rescaled_delta_n(nucl_num, 0:cord_num), een_rescaled_delta_n_gl(3,nucl_num, 0:cord_num)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num, kk
    +  double precision :: accu, accu2, cn
    +  integer*8                           :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  forces_jastrow_single_een = 0.0d0
    +
    +  if (cord_num == 0) return
    +
    +  do nw =1, walk_num
    +    een_rescaled_delta_n(:,:) = een_rescaled_single_n(:,:,nw) - een_rescaled_n(num,:,:,nw)
    +    do kk = 1,3
    +      een_rescaled_delta_n_gl(kk,:,:) = een_rescaled_single_n_gl(kk,:,:,nw) - een_rescaled_n_gl(num,kk,:,:,nw)
    +    end do
    +    do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        p = lkpm_combined_index(n, 3)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do a = 1, nucl_num
    +          cn = c_vector_full(a, n)
    +          if(cn == 0.d0) cycle
    +          do kk = 1, 3
    +            accu = 0.0d0
    +            do j = 1, elec_num
    +                accu = accu - een_rescaled_n_gl(j,kk,a,m,nw) * delta_p(j,a,m+l,k,nw) + &
    +                    een_rescaled_n(j,a,m,nw) * forces_delta_p(j,kk,a,m+l,k,nw)
    +            end do
    +            accu = accu - een_rescaled_delta_n_gl(kk,a,m) * (tmp_c(num,a,m+l,k,nw) + delta_p(num,a,m+l,k,nw)) + &
    +                een_rescaled_delta_n(a,m) * (forces_tmp_c(num,kk,a,m+l,k,nw) + forces_delta_p(num,kk,a,m+l,k,nw))
    +            forces_jastrow_single_een(kk,a,nw) = forces_jastrow_single_een(kk,a,nw) + accu * cn
    +
    +          end do
    +        end do
    +    end do
    +  end do
    +
    +
    +end function qmckl_compute_forces_jastrow_single_een_doc
    +
    +
    + +
    +
    function qmckl_compute_forces_jastrow_single_een_hpc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num, &
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     delta_p, forces_delta_p, tmp_c, forces_tmp_c, &
    +     een_rescaled_n, een_rescaled_single_n, een_rescaled_n_gl, een_rescaled_single_n_gl, forces_jastrow_single_een) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: dim_c_vector
    +  integer (c_int64_t) , intent(in)  , value :: cord_num
    +  integer(c_int64_t)   , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real(c_double)      , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real    (c_double ) , intent(in)          :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: forces_delta_p(elec_num, 3, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: forces_tmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(in)          :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real    (c_double ) , intent(out)         :: forces_jastrow_single_een(3,nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  double precision, allocatable :: een_rescaled_delta_n(:, :), een_rescaled_delta_n_gl(:,:,:)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num, kk
    +  double precision :: accu2, cn
    +  double precision, allocatable :: accu(:,:), tmp(:)
    +  double precision, external :: ddot
    +  integer :: elec_num4
    +
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  forces_jastrow_single_een = 0.0d0
    +
    +  if (cord_num == 0) return
    +
    +  allocate(een_rescaled_delta_n(nucl_num, 0:cord_num), een_rescaled_delta_n_gl(3,nucl_num, 0:cord_num), &
    +           accu(3,nucl_num), tmp(nucl_num))
    +
    +  elec_num4 = int(elec_num,4)
    +  do nw =1, walk_num
    +    een_rescaled_delta_n(:,:) = een_rescaled_single_n(:,:,nw) - een_rescaled_n(num,:,:,nw)
    +    een_rescaled_delta_n_gl(1:3,:,:) = een_rescaled_single_n_gl(1:3,:,:,nw) - een_rescaled_n_gl(num,1:3,:,:,nw)
    +    do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        p = lkpm_combined_index(n, 3)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do a = 1, nucl_num
    +          cn = c_vector_full(a, n)
    +          accu(1:3,a) = 0.0d0
    +          if(cn == 0.d0) cycle
    +          tmp(a) = tmp_c(num,a,m+l,k,nw) + delta_p(num,a,m+l,k,nw)
    +          call dgemv('T', elec_num4, 3, -1.d0, een_rescaled_n_gl(1,1,a,m,nw), elec_num4, &
    +                     delta_p(1,a,m+l,k,nw), 1, 0.d0, accu(1,a), 1)
    +          call dgemv('T', elec_num4, 3, 1.d0, forces_delta_p(1,1,a,m+l,k,nw), elec_num4, &
    +                     een_rescaled_n(1,a,m,nw), 1, 1.d0, accu(1,a), 1)
    +
    +        enddo
    +
    +        accu(1,:) = accu(1,:) - een_rescaled_delta_n_gl(1,:,m)*tmp(:)
    +        accu(2,:) = accu(2,:) - een_rescaled_delta_n_gl(2,:,m)*tmp(:)
    +        accu(3,:) = accu(3,:) - een_rescaled_delta_n_gl(3,:,m)*tmp(:)
    +
    +        accu(1,:) = accu(1,:) + een_rescaled_delta_n(:,m)*forces_tmp_c(num,1,:,m+l,k,nw)
    +        accu(2,:) = accu(2,:) + een_rescaled_delta_n(:,m)*forces_tmp_c(num,2,:,m+l,k,nw)
    +        accu(3,:) = accu(3,:) + een_rescaled_delta_n(:,m)*forces_tmp_c(num,3,:,m+l,k,nw)
    +
    +        accu(1,:) = accu(1,:) + een_rescaled_delta_n(:,m)*forces_delta_p(num,1,:,m+l,k,nw)
    +        accu(2,:) = accu(2,:) + een_rescaled_delta_n(:,m)*forces_delta_p(num,2,:,m+l,k,nw)
    +        accu(3,:) = accu(3,:) + een_rescaled_delta_n(:,m)*forces_delta_p(num,3,:,m+l,k,nw)
    +
    +        forces_jastrow_single_een(1,:,nw) = forces_jastrow_single_een(1,:,nw) + accu(1,:) * c_vector_full(:,n)
    +        forces_jastrow_single_een(2,:,nw) = forces_jastrow_single_een(2,:,nw) + accu(2,:) * c_vector_full(:,n)
    +        forces_jastrow_single_een(3,:,nw) = forces_jastrow_single_een(3,:,nw) + accu(3,:) * c_vector_full(:,n)
    +    end do
    +  end do
    +
    +
    +end function qmckl_compute_forces_jastrow_single_een_hpc
    +
    +
    +
    +
    +
    +
    +
    + +
    +

    5. Forces of the orbitals

    +
    +
    +
    +

    5.1. Force of AO value

    +
    +

    +Computes the forces on the values of the atomic orbitals (AO). These are equal to the gradients of the AOs multiplied with a minus sign, and summed over different indices. +

    +
    + +
    +

    5.1.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_ao_value(qmckl_context context,
    +                                     double* const forces_ao_value,
    +                                     const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.1.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    ao_numint64_tinNumber of AOs
    shell_numint64_tinNumber of shells
    point_numint64_tinNumber of points
    nucl_numint64_tinNumber of nuclei
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_shell_numint64_t[nucl_num]inNumber of shells per nucleus
    shell_ang_momint32_t[shell_num]inAngular momentum of each shell
    ao_factordouble[ao_num]inNormalization factor of the AOs
    ao_vgldouble[point_num][5][shell_num]inValue, gradients and Laplacian of the shells
    forces_ao_valuedouble[nucl_num][point_num][3][ao_num]outForces of the AOs
    + +
    +
    function qmckl_compute_forces_ao_value_doc(context, &
    +     ao_num, shell_num, point_num, nucl_num, &
    +     nucleus_index, nucleus_shell_num, &
    +     shell_ang_mom, ao_factor, ao_vgl, forces_ao_value) &
    +     bind(C) result(info)
    +  use qmckl_constants
    +  use qmckl, only : qmckl_ao_polynomial_vgl, qmckl_get_numprec_precision
    +  implicit none
    +  integer (qmckl_context), intent(in)  , value :: context
    +  integer (c_int64_t) , intent(in)  , value :: ao_num
    +  integer (c_int64_t) , intent(in)  , value :: shell_num
    +  integer (c_int64_t) , intent(in)  , value :: point_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)          :: nucleus_index(nucl_num)
    +  integer (c_int64_t) , intent(in)          :: nucleus_shell_num(nucl_num)
    +  integer (c_int32_t) , intent(in)          :: shell_ang_mom(shell_num)
    +  real    (c_double ) , intent(in)          :: ao_factor(ao_num)
    +  real    (c_double ) , intent(in)          :: ao_vgl(ao_num,5,point_num)
    +  real    (c_double ) , intent(out)         :: forces_ao_value(ao_num,3,point_num,nucl_num)
    +  integer(qmckl_exit_code) :: info
    +
    +  integer           :: l, il, k
    +  integer*8         :: ipoint, inucl
    +  integer*8         :: ishell_start, ishell_end, ishell
    +  integer           :: lstart(0:20)
    +  double precision  :: x, y, z, r2
    +  double precision  :: cutoff
    +
    +  integer         , allocatable  ::  ao_index(:)
    +  allocate(ao_index(ao_num))
    +
    +  !forces_ao_value = 0.d0
    +
    +  ! Pre-computed data
    +  do l=0,20
    +     lstart(l) = l*(l+1)*(l+2)/6 +1
    +  end do
    +
    +  k=1
    +  do inucl=1,nucl_num
    +     ishell_start = nucleus_index(inucl) + 1
    +     ishell_end   = nucleus_index(inucl) + nucleus_shell_num(inucl)
    +     do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        ao_index(ishell) = k
    +        k = k + lstart(l+1) - lstart(l)
    +     end do
    +  end do
    +  info = QMCKL_SUCCESS
    +
    +
    +  do ipoint = 1, point_num
    +     do inucl=1,nucl_num
    +        ! Loop over shells
    +        ishell_start = nucleus_index(inucl) + 1
    +        ishell_end   = nucleus_index(inucl) + nucleus_shell_num(inucl)
    +        do ishell = ishell_start, ishell_end
    +           l = shell_ang_mom(ishell)
    +           do k = ao_index(ishell), ao_index(ishell) + lstart(l+1)-lstart(l) -1
    +              forces_ao_value(k,1,ipoint,inucl) = -ao_vgl(k,2,ipoint)
    +              forces_ao_value(k,2,ipoint,inucl) = -ao_vgl(k,3,ipoint)
    +              forces_ao_value(k,3,ipoint,inucl) = -ao_vgl(k,4,ipoint)
    +           end do
    +        end do
    +     end do
    +  end do
    +
    +  deallocate(ao_index)
    +
    +end function qmckl_compute_forces_ao_value_doc
    +
    +
    +
    +
    +
    + +
    +

    5.2. Force of MO value

    +
    +

    +Calculates the force on the molecular orbitals (MO) values. These are calculated by taking a linear combination of AOs. +

    +
    + +
    +

    5.2.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_mo_value(qmckl_context context,
    +                          double* const forces_mo_value,
    +                          const int64_t size_max);
    +
    +
    + +
    +
    qmckl_exit_code
    +qmckl_get_forces_mo_value_inplace (qmckl_context context,
    +                                     double* const forces_mo_value,
    +                                     const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.2.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    nucl_numint64_tinNumber of AOs
    ao_numint64_tinNumber of AOs
    mo_numint64_tinNumber of MOs
    point_numint64_tinNumber of points
    shell_numint64_tinNumber of shells
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_shell_numint64_t[nucl_num]inNumber of shells per nucleus
    shell_ang_momint32_t[shell_num]inAngular momentum of each shell
    coefficient_tdouble[mo_num][ao_num]inTranspose of the AO to MO transformation matrix
    ao_vgldouble[point_num][3][ao_num]inAO values, gradient and Laplacian
    forces_mo_valuedouble[nucl_num][point_num][3][mo_num]outForces of MOs
    + + +
    +
    integer(qmckl_exit_code)  function qmckl_compute_forces_mo_value_doc(context, &
    +     nucl_num,ao_num, mo_num, point_num, shell_num, nucleus_index, nucleus_shell_num, &
    +     shell_ang_mom, coefficient_t, ao_vgl, forces_mo_value) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)        :: context
    +  integer(c_int64_t)    , intent(in), value ::nucl_num, ao_num, mo_num, point_num, shell_num
    +  real(c_double)      , intent(in)          :: ao_vgl(ao_num,5,point_num)
    +  real(c_double)      , intent(in)          :: coefficient_t(mo_num,ao_num)
    +  integer (c_int64_t) , intent(in)          :: nucleus_index(nucl_num)
    +  integer (c_int64_t) , intent(in)          :: nucleus_shell_num(nucl_num)
    +  integer (c_int32_t) , intent(in)          :: shell_ang_mom(shell_num)
    +  real(c_double)      , intent(out)         :: forces_mo_value(mo_num,3,point_num,nucl_num)
    +
    +
    +  integer*8 :: i,j,a, m, ishell_start, ishell_end, il, ishell
    +  integer :: l, k
    +  double precision :: c1, c2, c3, coef
    +
    +  integer, allocatable  ::  ao_index(:)
    +  integer           :: lstart(0:20)
    +
    +  allocate(ao_index(ao_num))
    +
    +  do l=0,20
    +    lstart(l) = l*(l+1)*(l+2)/6 +1
    +  end do
    +
    +  k=1
    +  do a=1,nucl_num
    +     ishell_start = nucleus_index(a) + 1
    +     ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +     do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        ao_index(ishell) = k
    +        k = k + lstart(l+1) - lstart(l)
    +     end do
    +  end do
    +
    +
    +  info = QMCKL_SUCCESS
    +  do a=1,nucl_num
    +    ishell_start = nucleus_index(a) + 1
    +    ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +    do j=1,point_num
    +      forces_mo_value(:,:,j,a) = 0.0d0
    +      do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        do k=ao_index(ishell), ao_index(ishell) + lstart(l+1)-lstart(l)-1
    +          c1 = ao_vgl(k,2,j)
    +          c2 = ao_vgl(k,3,j)
    +          c3 = ao_vgl(k,4,j)
    +          do i=1,mo_num
    +            coef = coefficient_t(i,k)
    +            forces_mo_value(i,1,j,a) = forces_mo_value(i,1,j,a) - c1 * coef
    +            forces_mo_value(i,2,j,a) = forces_mo_value(i,2,j,a) - c2 * coef
    +            forces_mo_value(i,3,j,a) = forces_mo_value(i,3,j,a) - c3 * coef
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +  deallocate(ao_index)
    +
    +
    +
    +end function qmckl_compute_forces_mo_value_doc
    +
    +
    + + +
    +
    qmckl_exit_code qmckl_compute_forces_mo_value_doc (
    +      const qmckl_context context,
    +      const int64_t nucl_num,
    +      const int64_t ao_num,
    +      const int64_t mo_num,
    +      const int64_t point_num,
    +      const int64_t shell_num,
    +      const int64_t* nucleus_index,
    +      const int64_t* nucleus_shell_num,
    +      const int32_t* shell_ang_mom,
    +      const double* coefficient_t,
    +      const double* ao_vgl,
    +      double* const forces_mo_value );
    +
    +
    +
    +
    +
    + +
    +

    5.3. Force of MO gradient

    +
    +

    +Calculates the forces of the gradients of the MOs. These are calculated by taking a linear combination of the required components of the Hessian of the AOs. +

    +
    + +
    +

    5.3.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_mo_g(qmckl_context context,
    +                          double* const forces_mo_g,
    +                          const int64_t size_max);
    +
    +qmckl_exit_code
    +qmckl_get_forces_mo_g_inplace(qmckl_context context,
    +                              double* const forces_mo_g,
    +                              const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.3.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    ao_numint64_tinNumber of AOs
    mo_numint64_tinNumber of MOs
    point_numint64_tinNumber of points
    nucl_numint64_tinNumber of nuclei
    shell_numint64_tinNumber of shells
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_shell_numint64_t[nucl_num]inNumber of shells per nucleus
    shell_ang_momint32_t[shell_num]inAngular momentum of each shell
    coefficient_tdouble[mo_num][ao_num]inTranspose of the AO to MO transformation matrix
    ao_hessiandouble[3][point_num][4][ao_num]inHessian of AOs
    forces_mo_gdouble[nucl_num][3][point_num][3][mo_num]outForces on gradients of MOs
    + + +
    +
    integer function qmckl_compute_forces_mo_g_doc(context, &
    +     ao_num, mo_num, point_num, nucl_num, &
    +     shell_num, nucleus_index, nucleus_shell_num, shell_ang_mom, &
    +     coefficient_t, ao_hessian, forces_mo_g) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in), value  :: context
    +  integer (c_int64_t)   , intent(in), value  :: nucl_num, ao_num, mo_num, point_num, shell_num
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_index(nucl_num)
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_shell_num(nucl_num)
    +  integer (c_int32_t) ,   intent(in)         :: shell_ang_mom(shell_num)
    +  real    (c_double )   , intent(in)         :: coefficient_t(mo_num,ao_num)
    +  real    (c_double )   , intent(in)         :: ao_hessian(ao_num,4,point_num,3)
    +  real    (c_double )   , intent(out)        :: forces_mo_g(mo_num,3,point_num,3,nucl_num)
    +  integer*8 :: i,j, m, n,a
    +  double precision :: c1
    +
    +  double precision, allocatable :: tmp(:,:,:,:)
    +
    +  allocate(tmp(ao_num,3,point_num,3))
    +  do a=1,nucl_num
    +  ! BROKEN
    +     tmp(:,1:3,:,:) = ao_hessian(:,1:3,:,:)
    +     info = qmckl_dgemm(context, 'N', 'N', mo_num, 3*point_num*3, ao_num, &
    +       -1.d0, coefficient_t, mo_num, &
    +       tmp, ao_num, 0.d0, forces_mo_g(1,1,1,1,a), mo_num)
    +     if (info /= 0) return
    +  end do
    +
    +
    +  deallocate(tmp)
    +
    +end function qmckl_compute_forces_mo_g_doc
    +
    +
    + +
    +
    integer function qmckl_compute_forces_mo_g_hpc(context, &
    +     ao_num, mo_num, point_num, nucl_num, &
    +     shell_num, nucleus_index, nucleus_shell_num, shell_ang_mom, &
    +     coefficient_t, ao_hessian, forces_mo_g) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in), value  :: context
    +  integer (c_int64_t)   , intent(in), value  :: nucl_num, ao_num, mo_num, point_num, shell_num
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_index(nucl_num)
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_shell_num(nucl_num)
    +  integer (c_int32_t) ,   intent(in)         :: shell_ang_mom(shell_num)
    +  real    (c_double )   , intent(in)         :: coefficient_t(mo_num,ao_num)
    +  real    (c_double )   , intent(in)         :: ao_hessian(ao_num,4,point_num,3)
    +  real    (c_double )   , intent(out)        :: forces_mo_g(mo_num,3,point_num,3,nucl_num)
    +  integer*8 :: i,j, m, n,a
    +  double precision :: c1
    +
    +  integer           :: l, il, k, ao_ind
    +  integer*8         :: ishell_start, ishell_end, ishell
    +  integer           :: lstart(0:20)
    +
    +  integer         , allocatable  ::  ao_index(:)
    +  allocate(ao_index(ao_num))
    +
    +  do l=0,20
    +     lstart(l) = l*(l+1)*(l+2)/6 +1
    +  end do
    +
    +  k=1
    +  do a=1,nucl_num
    +     ishell_start = nucleus_index(a) + 1
    +     ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +     do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        ao_index(ishell) = k
    +        k = k + lstart(l+1) - lstart(l)
    +     end do
    +  end do
    +  info = QMCKL_SUCCESS
    +
    +
    +  do a=1,nucl_num
    +     ishell_start = nucleus_index(a) + 1
    +     ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +     do n = 1, 3
    +        do j=1,point_num
    +           forces_mo_g(:,:,j,n,a) = 0.d0
    +           do m = 1, 3
    +              do ishell = ishell_start, ishell_end
    +                 l = shell_ang_mom(ishell)
    +                 il = lstart(l+1)-lstart(l)
    +                 ao_ind = ao_index(ishell) 
    +                 do k = ao_ind, ao_ind + il - 1
    +                    c1 = ao_hessian(k, m, j, n)
    +                    if (c1 /= 0.d0) then
    +                       do i=1,mo_num
    +                          forces_mo_g(i, m, j, n, a) = forces_mo_g(i, m, j, n, a) - &
    +                               coefficient_t(i,k) * c1
    +                       end do
    +                    end if
    +                 end do
    +              end do
    +           end do
    +        end do
    +     end do
    +  end do
    +
    +  deallocate(ao_index)
    +
    +
    +end function qmckl_compute_forces_mo_g_hpc
    +
    +
    + +
    +
    qmckl_exit_code qmckl_compute_forces_mo_g (
    +         const qmckl_context context,
    +         const int64_t ao_num,
    +         const int64_t mo_num,
    +         const int64_t point_num,
    +         const int64_t nucl_num,
    +         const int64_t shell_num,
    +         const int64_t* nucleus_index,
    +         const int64_t* nucleus_shell_num,
    +         const int32_t* shell_ang_mom,
    +         const double* coefficient_t,
    +         const double* ao_hessian,
    +         double* const forces_mo_g );
    +
    +qmckl_exit_code qmckl_compute_forces_mo_g_doc (
    +         const qmckl_context context,
    +         const int64_t ao_num,
    +         const int64_t mo_num,
    +         const int64_t point_num,
    +         const int64_t nucl_num,
    +         const int64_t shell_num,
    +         const int64_t* nucleus_index,
    +         const int64_t* nucleus_shell_num,
    +         const int32_t* shell_ang_mom,
    +         const double* coefficient_t,
    +         const double* ao_hessian,
    +         double* const forces_mo_g );
    +
    +qmckl_exit_code qmckl_compute_forces_mo_g_hpc (
    +         const qmckl_context context,
    +         const int64_t ao_num,
    +         const int64_t mo_num,
    +         const int64_t point_num,
    +         const int64_t nucl_num,
    +         const int64_t shell_num,
    +         const int64_t* nucleus_index,
    +         const int64_t* nucleus_shell_num,
    +         const int32_t* shell_ang_mom,
    +         const double* coefficient_t,
    +         const double* ao_hessian,
    +         double* const forces_mo_g );
    +
    +
    +
    +
    +
    + +
    +

    5.4. Force of MO Laplacian

    +
    +

    +Computes the forces on the Laplacian of the MOs. They are calculated by taking a linear combination of the ao_hessian[:,:,:,3,:] components of the AO Hessian. These store the derivatives of the Laplacian of the AO. +

    +
    + +
    +

    5.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_forces_mo_l(qmckl_context context,
    +                          double* const forces_mo_l,
    +                          const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.4.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    ao_numint64_tinNumber of AOs
    mo_numint64_tinNumber of MOs
    point_numint64_tinNumber of points
    nucl_numint64_tinNumber of nuclei
    shell_numint64_tinNumber of shells
    nucleus_indexint64_t[nucl_num]inIndex of the 1st shell of each nucleus
    nucleus_shell_numint64_t[nucl_num]inNumber of shells per nucleus
    shell_ang_momint32_t[shell_num]inAngular momentum of each shell
    coefficient_tdouble[mo_num][ao_num]inTranspose of the AO to MO transformation matrix
    ao_hessiandouble[3][point_num][4][ao_num]inHessian of AOs
    forces_mo_ldouble[nucl_num][3][point_num][mo_num]outForces on MO Laplacian
    + + +
    +
    integer function qmckl_compute_forces_mo_l_doc(context, &
    +     ao_num, mo_num, point_num, nucl_num, &
    +     shell_num, nucleus_index, nucleus_shell_num, shell_ang_mom, &
    +     coefficient_t, ao_hessian, forces_mo_l) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in), value  :: context
    +  integer (c_int64_t)   , intent(in), value  :: nucl_num, ao_num, mo_num, point_num, shell_num
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_index(nucl_num)
    +  integer (c_int64_t) ,   intent(in)         :: nucleus_shell_num(nucl_num)
    +  integer (c_int32_t) ,   intent(in)         :: shell_ang_mom(shell_num)
    +  real    (c_double )   , intent(in)         :: coefficient_t(mo_num,ao_num)
    +  real    (c_double )   , intent(in)         :: ao_hessian(ao_num,4,point_num,3)
    +  real    (c_double )   , intent(out)        :: forces_mo_l(mo_num,point_num,3,nucl_num)
    +  integer*8 :: i,j, m, n,a, il, ishell, ishell_start, ishell_end
    +  integer           :: lstart(0:20)
    +  integer           :: l, k
    +  double precision :: c1
    +
    +  integer         , allocatable  ::  ao_index(:)
    +  allocate(ao_index(ao_num))
    +
    +  do l=0,20
    +    lstart(l) = l*(l+1)*(l+2)/6 +1
    +  end do
    +
    +  k=1
    +  do a=1,nucl_num
    +     ishell_start = nucleus_index(a) + 1
    +     ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +     do ishell = ishell_start, ishell_end
    +        l = shell_ang_mom(ishell)
    +        ao_index(ishell) = k
    +        k = k + lstart(l+1) - lstart(l)
    +     end do
    +  end do
    +
    +  forces_mo_l = 0.d0
    +  info = QMCKL_SUCCESS
    +
    +  do a=1, nucl_num
    +    ishell_start = nucleus_index(a) + 1
    +    ishell_end   = nucleus_index(a) + nucleus_shell_num(a)
    +    do j=1,point_num
    +      do n = 1, 3
    +        do ishell = ishell_start, ishell_end
    +          k = ao_index(ishell)
    +          l = shell_ang_mom(ishell)
    +          do il = lstart(l), lstart(l+1)-1
    +            c1  = ao_hessian(k, 4, j, n)
    +            if (c1 == 0.d0) then
    +              k = k + 1
    +              cycle
    +            end if
    +            do i=1,mo_num
    +              forces_mo_l(i, j, n, a) = forces_mo_l(i, j, n, a) - coefficient_t(i,k) * c1
    +            end do
    +            k = k+1
    +          end do
    +        end do
    +      end do
    +    end do
    +  end do
    +
    +
    +  deallocate(ao_index)
    +
    +  !do a=1,nucl_num
    +  !  do m = 1, 3
    +  !   info = qmckl_dgemm(context,'N', 'N', mo_num, point_num, ao_num, &
    +  !              -1.d0, coefficient_t, mo_num, &
    +  !              ao_hessian(:, 4, :, m, a), ao_num, &
    +  !              1.d0, forces_mo_l(:, :, m, a), mo_num)
    +  !  end do
    +  !end do
    +
    +
    +
    +end function qmckl_compute_forces_mo_l_doc
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Author: TREX CoE

    +

    Created: 2025-04-29 Tue 08:44

    +

    Validate

    +
    + + diff --git a/qmckl_jastrow_champ.html b/qmckl_jastrow_champ.html index f9a90bb..d07e71f 100644 --- a/qmckl_jastrow_champ.html +++ b/qmckl_jastrow_champ.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + CHAMP Jastrow Factor @@ -258,172 +258,172 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Introduction

    +
    +

    1. Introduction

    The Jastrow factor depends on the electronic (\(\mathbf{r}\)) and @@ -526,8 +526,8 @@ The derivatives are computed with respect to the electron \(i\) for

    -
    -

    1.1. Reformulation of the three-body part

    +
    +

    1.1. Reformulation of the three-body part

    To accelerate the computation of the three-body part, the Jastrow @@ -592,14 +592,14 @@ the computation of \(J\) scales as \(\mathcal{O}(N_\text{elec}N_\text{nucl}n^2)\

    -
    -

    2. Context

    +
    +

    2. Context

    The following data stored in the context:

    - +
    @@ -992,8 +992,8 @@ Computed data:
    -
    -

    2.1. Data structure

    +
    +

    2.1. Data structure

    typedef struct qmckl_jastrow_champ_struct{
    @@ -1106,8 +1106,8 @@ this mechanism.
     
    -
    -

    2.2. Initialization functions

    +
    +

    2.2. Initialization functions

    To prepare for the Jastrow and its derivative, all the following functions need to be @@ -1136,8 +1136,8 @@ are precontracted using BLAS LEVEL 3 operations.

    -
    -
    2.2.0.1. Fortran interface
    +
    +
    2.2.0.1. Fortran interface
    interface
    @@ -1252,8 +1252,8 @@ are precontracted using BLAS LEVEL 3 operations.
     
    -
    -

    2.3. Access functions

    +
    +

    2.3. Access functions

    Along with these core functions, calculation of the jastrow factor @@ -1272,8 +1272,8 @@ function returns true.

    -
    -
    2.3.0.1. Fortran interface
    +
    +
    2.3.0.1. Fortran interface
    interface
    @@ -1389,8 +1389,8 @@ function returns true.
     
    -
    -

    3. Computation

    +
    +

    3. Computation

    The computed data is stored in the context so that it can be reused @@ -1403,12 +1403,12 @@ current date is stored.

    -
    -

    3.1. Electron-electron component

    +
    +

    3.1. Electron-electron component

    -
    -

    3.1.1. Asymptotic component

    +
    +

    3.1.1. Asymptotic component

    Calculate the asymptotic component asymp_jasb to be subtracted from the @@ -1427,8 +1427,8 @@ If the spin_independent variable is set to 1, then

    -
    -
    3.1.1.1. Get
    +
    +
    3.1.1.1. Get
    qmckl_exit_code
    @@ -1440,7 +1440,7 @@ If the spin_independent variable is set to 1, then
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -1461,10 +1461,10 @@ If the spin_independent variable is set to 1, then
       
    -
    -
    3.1.1.2. Compute
    +
    +
    3.1.1.2. Compute
    - +
    @@ -1637,8 +1637,8 @@ If the spin_independent variable is set to 1, then -
    -

    3.1.2. Electron-electron rescaled distances

    +
    +

    3.1.2. Electron-electron rescaled distances

    ee_distance_rescaled stores the matrix of the rescaled distances between all @@ -1656,8 +1656,8 @@ where \(r_{ij}\) is the matrix of electron-electron distances.

    -
    -
    3.1.2.1. Get
    +
    +
    3.1.2.1. Get
    qmckl_exit_code qmckl_get_jastrow_champ_ee_distance_rescaled(qmckl_context context,
    @@ -1668,10 +1668,10 @@ where \(r_{ij}\) is the matrix of electron-electron distances.
     
    -
    -
    3.1.2.2. Compute
    +
    +
    3.1.2.2. Compute
    -
    +
    @@ -1788,8 +1788,8 @@ where \(r_{ij}\) is the matrix of electron-electron distances. -
    -

    3.1.3. Electron-electron rescaled distance gradients and Laplacian with respect to electron coordinates

    +
    +

    3.1.3. Electron-electron rescaled distance gradients and Laplacian with respect to electron coordinates

    The rescaled distances, represented by \(C_{ij} = (1 - e^{-\kappa_\text{e} r_{ij}})/\kappa_\text{e}\) @@ -1801,8 +1801,8 @@ direction derivatives, while the fourth index corresponds to the Laplacian.

    -
    -
    3.1.3.1. Get
    +
    +
    3.1.3.1. Get
    qmckl_exit_code qmckl_get_jastrow_champ_ee_distance_rescaled_gl(qmckl_context context,
    @@ -1813,10 +1813,10 @@ direction derivatives, while the fourth index corresponds to the Laplacian.
     
    -
    -
    3.1.3.2. Compute
    +
    +
    3.1.3.2. Compute
    -
    +
    @@ -1932,8 +1932,8 @@ direction derivatives, while the fourth index corresponds to the Laplacian. -
    -

    3.1.4. Electron-electron component

    +
    +

    3.1.4. Electron-electron component

    Calculate the electron-electron jastrow component factor_ee using the asymp_jasb @@ -1966,8 +1966,8 @@ If the spin_independent variable is set to 1, then

    -
    -
    3.1.4.1. Get
    +
    +
    3.1.4.1. Get
    qmckl_exit_code
    @@ -1979,7 +1979,7 @@ If the spin_independent variable is set to 1, then
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -2000,10 +2000,10 @@ If the spin_independent variable is set to 1, then
       
    -
    -
    3.1.4.2. Compute
    +
    +
    3.1.4.2. Compute
    -
    +
    @@ -2288,8 +2288,8 @@ If the spin_independent variable is set to 1, then -
    -

    3.1.5. Derivative

    +
    +

    3.1.5. Derivative

    The derivative of factor_ee is computed using the ee_distance_rescaled and @@ -2315,8 +2315,8 @@ directions and the laplacian as the last component.

    -
    -
    3.1.5.1. Get
    +
    +
    3.1.5.1. Get
    qmckl_exit_code
    @@ -2328,7 +2328,7 @@ directions and the laplacian as the last component.
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -2349,10 +2349,10 @@ directions and the laplacian as the last component.
       
    -
    -
    3.1.5.2. Compute
    +
    +
    3.1.5.2. Compute
    -
    +
    @@ -2734,12 +2734,12 @@ directions and the laplacian as the last component. -
    -

    3.2. Electron-nucleus component

    +
    +

    3.2. Electron-nucleus component

    -
    -

    3.2.1. Asymptotic component

    +
    +

    3.2.1. Asymptotic component

    Calculate the asymptotic component asymp_jasa to be subtracted from the final @@ -2754,8 +2754,8 @@ via the a_vector and the electron-nucleus rescale factors res

    -
    -
    3.2.1.1. Get
    +
    +
    3.2.1.1. Get
    qmckl_exit_code
    @@ -2767,7 +2767,7 @@ via the a_vector and the electron-nucleus rescale factors res
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -2788,10 +2788,10 @@ via the a_vector and the electron-nucleus rescale factors res
       
    -
    -
    3.2.1.2. Compute
    +
    +
    3.2.1.2. Compute
    -
    +
    @@ -2919,8 +2919,8 @@ via the a_vector and the electron-nucleus rescale factors res -
    -

    3.2.2. Electron-nucleus rescaled distances

    +
    +

    3.2.2. Electron-nucleus rescaled distances

    en_distance_rescaled stores the matrix of the rescaled distances between @@ -2938,8 +2938,8 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances.

    -
    -
    3.2.2.1. Get
    +
    +
    3.2.2.1. Get
    qmckl_exit_code
    @@ -2952,10 +2952,10 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances.
     
    -
    -
    3.2.2.2. Compute
    +
    +
    3.2.2.2. Compute
    -
    +
    @@ -3112,8 +3112,8 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances. -
    -

    3.2.3. Electron-electron rescaled distance gradients and Laplacian with respect to electron coordinates

    +
    +

    3.2.3. Electron-electron rescaled distance gradients and Laplacian with respect to electron coordinates

    The rescaled distances, represented by \(C_{i\alpha} = (1 - e^{-\kappa_\alpha R_{i\alpha}})/\kappa\) @@ -3125,8 +3125,8 @@ direction derivatives, while the fourth index corresponds to the Laplacian.

    -
    -
    3.2.3.1. Get
    +
    +
    3.2.3.1. Get
    qmckl_exit_code
    @@ -3138,10 +3138,10 @@ direction derivatives, while the fourth index corresponds to the Laplacian.
     
    -
    -
    3.2.3.2. Compute
    +
    +
    3.2.3.2. Compute
    -
    +
    @@ -3298,8 +3298,8 @@ direction derivatives, while the fourth index corresponds to the Laplacian. -
    -

    3.2.4. Electron-nucleus component

    +
    +

    3.2.4. Electron-nucleus component

    Calculate the electron-electron jastrow component factor_en using the a_vector @@ -3314,8 +3314,8 @@ coeffecients and the electron-nucleus rescaled distances en_distance_resca

    -
    -
    3.2.4.1. Get
    +
    +
    3.2.4.1. Get
    qmckl_exit_code
    @@ -3327,7 +3327,7 @@ coeffecients and the electron-nucleus rescaled distances en_distance_resca
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -3348,10 +3348,10 @@ coeffecients and the electron-nucleus rescaled distances en_distance_resca
       
    -
    -
    3.2.4.2. Compute
    +
    +
    3.2.4.2. Compute
    -
    +
    @@ -3577,8 +3577,8 @@ coeffecients and the electron-nucleus rescaled distances en_distance_resca -
    -

    3.2.5. Derivative

    +
    +

    3.2.5. Derivative

    Calculate the electron-electron jastrow component factor_en_gl derivative @@ -3607,8 +3607,8 @@ The formula is given by:

    -
    -
    3.2.5.1. Get
    +
    +
    3.2.5.1. Get
    qmckl_exit_code
    @@ -3620,7 +3620,7 @@ The formula is given by:
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -3641,10 +3641,10 @@ The formula is given by:
       
    -
    -
    3.2.5.2. Compute
    +
    +
    3.2.5.2. Compute
    -
    +
    @@ -3850,8 +3850,8 @@ The formula is given by: -
    -
    3.2.5.3. Test
    +
    +
    3.2.5.3. Test
    /* Check if Jastrow is properly initialized */
    @@ -4009,12 +4009,12 @@ The formula is given by:
     
    -
    -

    3.3. Electron-electron-nucleus component

    +
    +

    3.3. Electron-electron-nucleus component

    -
    -

    3.3.1. Electron-electron rescaled distances in \(J_\text{eeN}\)

    +
    +

    3.3.1. Electron-electron rescaled distances in \(J_\text{eeN}\)

    een_rescaled_e stores the table of the rescaled distances between all @@ -4034,12 +4034,12 @@ where \(r_{ij}\) is the matrix of electron-electron distances.

    -
    -
    3.3.1.1. Get
    +
    +
    3.3.1.1. Get
    qmckl_exit_code
    -qmckl_get_jastrow_champ_een_distance_rescaled_e(qmckl_context context,
    +qmckl_get_jastrow_champ_een_rescaled_e(qmckl_context context,
                                                     double* const een_rescaled_e,
                                                     const int64_t size_max);
     
    @@ -4047,10 +4047,10 @@ where \(r_{ij}\) is the matrix of electron-electron distances.
    -
    -
    3.3.1.2. Compute
    +
    +
    3.3.1.2. Compute
    -
    +
    @@ -4365,13 +4365,112 @@ where \(r_{ij}\) is the matrix of electron-electron distances. -
    -
    3.3.1.3. Test
    +
    +
    3.3.1.3. Test
    +
    +
    +
    assert(qmckl_electron_provided(context));
    +{
    +
    +  double een_rescaled_e[walk_num][(cord_num + 1)][elec_num][elec_num];
    +  rc = qmckl_get_jastrow_champ_een_rescaled_e(context, &(een_rescaled_e[0][0][0][0]),elec_num*elec_num*(cord_num+1)*walk_num);
    +
    +  assert( fabs(een_rescaled_e[0][0][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][0][1] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][0][2] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][1][0] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][1][2] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][2][0] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][2][1] - (1.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][0][2][2] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][0][1] - (0.6191495547586775)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][0][2] - (0.2211015082992776)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][1][0] - (0.6191495547586775)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][1][2] - (0.1891080158548495)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][2][0] - (0.2211015082992776)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][2][1] - (0.1891080158548495)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][1][2][2] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][0][1] - (0.38334617115786856)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][0][2] - (0.048885876972215525)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][1][0] - (0.38334617115786856)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][1][2] - (0.03576184166055801)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][2][0] - (0.048885876972215525)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][2][1] - (0.03576184166055801)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][2][2][2] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][0][1] - (0.23734861119083814)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][0][2] - (0.010808741133089782)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][1][0] - (0.23734861119083814)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][1][2] - (0.006762850919743422)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][2][0] - (0.010808741133089782)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][2][1] - (0.006762850919743422)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][3][2][2] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][0][1] - (0.14695428694139787)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][0][2] - (0.002389828967342592)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][1][0] - (0.14695428694139787)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][1][2] - (0.0012789093189548221)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][2][0] - (0.002389828967342592)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][2][1] - (0.0012789093189548221)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][4][2][2] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][0][0] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][0][1] - (0.09098668132964542)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][0][2] - (0.0005283947892567522)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][1][0] - (0.09098668132964542)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][1][1] - (0.0)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][1][2] - (0.0002418520037658232)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][2][0] - (0.0005283947892567522)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][2][1] - (0.0002418520037658232)) < 1.e-10 );
    +  assert( fabs(een_rescaled_e[0][5][2][2] - (0.0)) < 1.e-10 );
    +}
    +
    +{
    +  printf("een_rescaled_e_hpc\n");
    +  double ee_distance[walk_num * elec_num * elec_num];
    +  rc = qmckl_get_electron_ee_distance(context, &(ee_distance[0]), walk_num*elec_num*elec_num);
    +  assert(rc == QMCKL_SUCCESS);
    +
    +  double een_rescaled_e_doc[walk_num][cord_num+1][elec_num][elec_num];
    +  memset(&(een_rescaled_e_doc[0][0][0][0]), 0, sizeof(een_rescaled_e_doc));
    +  rc = qmckl_compute_een_rescaled_e(context, walk_num, elec_num, cord_num,
    +                                    rescale_factor_ee, &(ee_distance[0]), &(een_rescaled_e_doc[0][0][0][0]));
    +  assert(rc == QMCKL_SUCCESS);
    +
    +  double een_rescaled_e_hpc[walk_num][cord_num+1][elec_num][elec_num];
    +  memset(&(een_rescaled_e_hpc[0][0][0][0]), 0, sizeof(een_rescaled_e_hpc));
    +  rc = qmckl_compute_een_rescaled_e_hpc(context, walk_num, elec_num, cord_num,
    +                                        rescale_factor_ee, &(ee_distance[0]), &(een_rescaled_e_hpc[0][0][0][0]));
    +  assert(rc == QMCKL_SUCCESS);
    +
    +  for (int64_t i = 0; i < walk_num; i++) {
    +    for (int64_t j = 0; j < cord_num+1; j++) {
    +      for (int64_t k = 0; k < elec_num; k++) {
    +        for (int64_t l = 0; l < elec_num; l++) {
    +          if (fabs(een_rescaled_e_doc[i][j][k][l] - een_rescaled_e_hpc[i][j][k][l]) > 1.e-12) {
    +            printf("i=%ld j=%ld k=%ld l=%ld doc=%f hpc=%f\n", i, j, k, l, een_rescaled_e_doc[i][j][k][l], een_rescaled_e_hpc[i][j][k][l]);
    +            fflush(stdout);
    +          }
    +          assert(fabs(een_rescaled_e_doc[i][j][k][l] - een_rescaled_e_hpc[i][j][k][l]) < 1.e-8);
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +
    +
    -
    -

    3.3.2. Electron-electron rescaled distances derivatives in \(J_\text{eeN}\)

    +
    +

    3.3.2. Electron-electron rescaled distances derivatives in \(J_\text{eeN}\)

    een_rescaled_e_gl stores the table of the derivatives of the @@ -4396,23 +4495,23 @@ Derivatives are set to zero at \(r_{ii}\) to avoid NaNs.

    -
    -
    3.3.2.1. Get
    +
    +
    3.3.2.1. Get
    qmckl_exit_code
    -qmckl_get_jastrow_champ_een_distance_rescaled_e_gl(qmckl_context context,
    -                                                   double* const een_rescaled_e_gl,
    -                                                   const int64_t size_max);
    +qmckl_get_jastrow_champ_een_rescaled_e_gl(qmckl_context context,
    +                                          double* const een_rescaled_e_gl,
    +                                          const int64_t size_max);
     
    -
    -
    3.3.2.2. Compute
    +
    +
    3.3.2.2. Compute
    -
    +
    @@ -4470,7 +4569,7 @@ Derivatives are set to zero at \(r_{ii}\) to avoid NaNs. - + @@ -4741,8 +4840,8 @@ Derivatives are set to zero at \(r_{ii}\) to avoid NaNs. -
    -

    3.3.3. Electron-nucleus rescaled distances in \(J_\text{eeN}\)

    +
    +

    3.3.3. Electron-nucleus rescaled distances in \(J_\text{eeN}\)

    een_rescaled_n stores the table of the rescaled distances between @@ -4760,8 +4859,8 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances.

    -
    -
    3.3.3.1. Get
    +
    +
    3.3.3.1. Get
    qmckl_exit_code
    @@ -4773,10 +4872,10 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances.
     
    -
    -
    3.3.3.2. Compute
    +
    +
    3.3.3.2. Compute
    -
    coord_eedouble[walk_num][3][elec_num]double[3][walk_num][elec_num] in Electron coordinates
    +
    @@ -5015,8 +5114,8 @@ where \(R_{i\alpha}\) is the matrix of electron-nucleus distances. -
    -

    3.3.4. Electron-nucleus rescaled distances derivatives in \(J_\text{eeN}\)

    +
    +

    3.3.4. Electron-nucleus rescaled distances derivatives in \(J_\text{eeN}\)

    een_rescaled_n_gl stores the table of the derivatives of the @@ -5037,8 +5136,8 @@ required for the een jastrowchamp.

    -
    -
    3.3.4.1. Get
    +
    +
    3.3.4.1. Get
    qmckl_exit_code
    @@ -5050,10 +5149,10 @@ required for the een jastrowchamp.
     
    -
    -
    3.3.4.2. Compute
    +
    +
    3.3.4.2. Compute
    -
    +
    @@ -5273,8 +5372,8 @@ required for the een jastrowchamp. -
    -

    3.3.5. Temporary arrays for electron-electron-nucleus Jastrow \(f_{een}\)

    +
    +

    3.3.5. Temporary arrays for electron-electron-nucleus Jastrow \(f_{een}\)

    Prepare c_vector_full and lkpm_combined_index tables required for the @@ -5303,8 +5402,8 @@ beginning of this section: \]

    -
    -
    3.3.5.1. Compute dimcvector
    +
    +
    3.3.5.1. Compute dimcvector

    Computes the dimension of the vector of parameters. @@ -5381,7 +5480,7 @@ Computes the dimension of the vector of parameters.

    - +
    @@ -5474,8 +5573,8 @@ Computes the dimension of the vector of parameters. -
    -
    3.3.5.2. Get
    +
    +
    3.3.5.2. Get
    qmckl_exit_code
    @@ -5492,10 +5591,10 @@ Computes the dimension of the vector of parameters.
     
    -
    -
    3.3.5.3. Compute cvectorfull
    +
    +
    3.3.5.3. Compute cvectorfull
    -
    +
    @@ -5679,10 +5778,10 @@ Computes the dimension of the vector of parameters. -
    -
    3.3.5.4. Compute lkpmcombinedindex
    +
    +
    3.3.5.4. Compute lkpmcombinedindex
    -
    +
    @@ -5879,10 +5978,10 @@ Computes the dimension of the vector of parameters. -
    -
    3.3.5.5. Compute tmpc
    +
    +
    3.3.5.5. Compute tmpc
    -
    +
    @@ -6057,10 +6156,10 @@ Computes the dimension of the vector of parameters. -
    -
    3.3.5.6. Compute dtmpc
    +
    +
    3.3.5.6. Compute dtmpc
    -
    +
    @@ -6224,8 +6323,8 @@ Computes the dimension of the vector of parameters. -
    -

    3.3.6. Electron-electron-nucleus Jastrow \(f_{een}\)

    +
    +

    3.3.6. Electron-electron-nucleus Jastrow \(f_{een}\)

    Calculate the electron-electron-nuclear three-body jastrow component factor_een @@ -6237,8 +6336,8 @@ TODO: write equations.

    -
    -
    3.3.6.1. Get
    +
    +
    3.3.6.1. Get
    qmckl_exit_code
    @@ -6250,7 +6349,7 @@ TODO: write equations.
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -6271,10 +6370,10 @@ TODO: write equations.
       
    -
    -
    3.3.6.2. Compute naive
    +
    +
    3.3.6.2. Compute naive
    -
    +
    @@ -6438,10 +6537,10 @@ TODO: write equations. -
    -
    3.3.6.3. Compute
    +
    +
    3.3.6.3. Compute
    -
    +
    @@ -6605,8 +6704,8 @@ TODO: write equations. -
    -

    3.3.7. Electron-electron-nucleus Jastrow \(f_{een}\) derivative

    +
    +

    3.3.7. Electron-electron-nucleus Jastrow \(f_{een}\) derivative

    Calculate the electron-electron-nuclear three-body jastrow component factor_een_gl @@ -6618,8 +6717,8 @@ TODO: write equations.

    -
    -
    3.3.7.1. Get
    +
    +
    3.3.7.1. Get
    qmckl_exit_code
    @@ -6639,7 +6738,7 @@ TODO: write equations.
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -6672,10 +6771,10 @@ TODO: write equations.
       
    -
    -
    3.3.7.2. Compute Naive
    +
    +
    3.3.7.2. Compute Naive
    -
    +
    @@ -6874,10 +6973,10 @@ TODO: write equations. -
    -
    3.3.7.3. Compute GL
    +
    +
    3.3.7.3. Compute GL
    -
    +
    @@ -7144,10 +7243,10 @@ TODO: write equations. -
    -
    3.3.7.4. Compute Gradient only
    +
    +
    3.3.7.4. Compute Gradient only
    -
    +
    @@ -7404,7 +7503,7 @@ TODO: write equations.
      -
    1. Test
      +
    2. Test
      /* Check if Jastrow is properly initialized */
      @@ -7434,20 +7533,20 @@ TODO: write equations.
       
      -
      -

      3.4. Total Jastrow

      +
      +

      3.4. Total Jastrow

      -
      -

      3.4.1. Value

      +
      +

      3.4.1. Value

      Value of the total Jastrow factor: \(\exp(J)\)

      -
      -
      3.4.1.1. Get
      +
      +
      3.4.1.1. Get
      qmckl_exit_code
      @@ -7459,7 +7558,7 @@ Value of the total Jastrow factor: \(\exp(J)\)
       
        -
      1. Fortran interface
        +
      2. Fortran interface
        interface
        @@ -7480,10 +7579,10 @@ Value of the total Jastrow factor: \(\exp(J)\)
         
      -
      -
      3.4.1.2. Compute
      +
      +
      3.4.1.2. Compute
      -
    +
    @@ -7653,8 +7752,8 @@ Value of the total Jastrow factor: \(\exp(J)\) -
    -

    3.4.2. Derivatives

    +
    +

    3.4.2. Derivatives

    Gradients and Laplacian of the total Jastrow factor: @@ -7668,8 +7767,8 @@ Gradients and Laplacian of the total Jastrow factor:

    -
    -
    3.4.2.1. Get
    +
    +
    3.4.2.1. Get
    qmckl_exit_code
    @@ -7694,7 +7793,7 @@ Gradients and Laplacian of the total Jastrow factor:
     
      -
    1. Fortran interface
      +
    2. Fortran interface
      interface
      @@ -7715,10 +7814,10 @@ Gradients and Laplacian of the total Jastrow factor:
       
    -
    -
    3.4.2.2. Compute GL
    +
    +
    3.4.2.2. Compute GL
    -
    +
    @@ -7914,7 +8013,7 @@ Gradients and Laplacian of the total Jastrow factor:
      -
    1. Test
      +
    2. Test
      printf("Total Jastrow derivatives\n");
      @@ -7979,10 +8078,10 @@ Gradients and Laplacian of the total Jastrow factor:
       
    -
    -
    3.4.2.3. Compute Gradient only
    +
    +
    3.4.2.3. Compute Gradient only
    -
    +
    @@ -8173,7 +8272,7 @@ Gradients and Laplacian of the total Jastrow factor:
      -
    1. Test
      +
    2. Test
      printf("Total Jastrow gradient only\n");
      @@ -8224,7 +8323,7 @@ Gradients and Laplacian of the total Jastrow factor:
       

      Author: TREX CoE

      -

      Created: 2025-04-02 Wed 13:00

      +

      Created: 2025-04-29 Tue 08:44

      Validate

      diff --git a/qmckl_jastrow_champ_single.html b/qmckl_jastrow_champ_single.html new file mode 100644 index 0000000..407f86f --- /dev/null +++ b/qmckl_jastrow_champ_single.html @@ -0,0 +1,6013 @@ + + + + + + + +CHAMP Jastrow Factor Single + + + + + + + + + + + + + +
      + UP + | + HOME +
      +

      CHAMP Jastrow Factor Single

      +
      +

      Table of Contents

      +
      + +
      +
      + +
      +

      1. Introduction

      +
      +

      +Single-electron move version of the Jastrow factor functions. The single-electron move calculates the difference between the old Jastrow values, gradients and derivatives and the new ones (if the single electron would have been moved). +That is to say, it calculates +\[ + \delta J = J(\mathbf{r}^\prime,\mathbf{R}) - J(\mathbf{r},\mathbf{R}) + \] +for all the neccessery quantities. +

      +
      +
      + +
      +

      2. Context

      +
      +
      +
      +

      2.1. Data structure

      +
      +
      +
      typedef struct qmckl_jastrow_champ_single_struct{
      +  int64_t      num;
      +  uint64_t     date;
      +  qmckl_matrix coord;
      +  double  *    een_rescaled_single_e;
      +  uint64_t     een_rescaled_single_e_date;
      +  uint64_t     een_rescaled_single_e_maxsize;
      +  double  *    een_rescaled_single_n;
      +  uint64_t     een_rescaled_single_n_date;
      +  uint64_t     een_rescaled_single_n_maxsize;
      +  double*      single_ee_distance;
      +  uint64_t     single_ee_distance_date;
      +  uint64_t     single_ee_distance_maxsize;
      +  double*      single_en_distance;
      +  uint64_t     single_en_distance_date;
      +  uint64_t     single_en_distance_maxsize;
      +  double*      delta_een;
      +  uint64_t     delta_een_date;
      +  uint64_t     delta_een_maxsize;
      +  double*      delta_p;
      +  uint64_t     delta_p_date;
      +  uint64_t     delta_p_maxsize;
      +  double*      ee_rescaled_single;
      +  uint64_t     ee_rescaled_single_date;
      +  uint64_t     ee_rescaled_single_maxsize;
      +  double*      en_rescaled_single;
      +  uint64_t     en_rescaled_single_date;
      +  uint64_t     en_rescaled_single_maxsize;
      +  double*      delta_en;
      +  uint64_t     delta_en_date;
      +  uint64_t     delta_en_maxsize;
      +  double*      delta_ee;
      +  uint64_t     delta_ee_date;
      +  uint64_t     delta_ee_maxsize;
      +  double  *    een_rescaled_single_e_gl;
      +  uint64_t     een_rescaled_single_e_gl_date;
      +  uint64_t     een_rescaled_single_e_gl_maxsize;
      +  double  *    een_rescaled_single_n_gl;
      +  uint64_t     een_rescaled_single_n_gl_date;
      +  uint64_t     een_rescaled_single_n_gl_maxsize;
      +  double*      delta_p_gl;
      +  uint64_t     delta_p_gl_date;
      +  uint64_t     delta_p_gl_maxsize;
      +  double*      delta_p_g;
      +  uint64_t     delta_p_g_date;
      +  uint64_t     delta_p_g_maxsize;
      +  double*      delta_een_gl;
      +  uint64_t     delta_een_gl_date;
      +  uint64_t     delta_een_gl_maxsize;
      +  double*      delta_een_g;
      +  uint64_t     delta_een_g_date;
      +  uint64_t     delta_een_g_maxsize;
      +  double*      ee_rescaled_single_gl;
      +  uint64_t     ee_rescaled_single_gl_date;
      +  uint64_t     ee_rescaled_single_gl_maxsize;
      +  double*      en_rescaled_single_gl;
      +  uint64_t     en_rescaled_single_gl_date;
      +  uint64_t     en_rescaled_single_gl_maxsize;
      +  double*      delta_en_gl;
      +  uint64_t     delta_en_gl_date;
      +  uint64_t     delta_en_gl_maxsize;
      +  double*      delta_ee_gl;
      +  uint64_t     delta_ee_gl_date;
      +  uint64_t     delta_ee_gl_maxsize;
      +
      +} qmckl_jastrow_champ_single_struct;
      +
      +
      +
      +
      +
      + +
      +

      3. Single point

      +
      +
      +
      +

      3.1. Set

      +
      +

      +We set the coordinates of the num-th electron for all walkers, where num is the electron which has to be moved. +The dimension of coord is +

      +
        +
      • [walknum][3] if transp is 'N'
      • +
      • [3][walknum] if transp is 'T'
      • +
      + +

      +Internally, the coordinates are stored in 'N' format as opposed to eleccoord. +This function has to be called before any other functions from this module. +

      + +
      +
      qmckl_exit_code qmckl_set_single_point (qmckl_context context,
      +                                 const char transp,
      +                                 const int64_t num,
      +                                 const double* coord,
      +                                 const int64_t size_max);
      +
      +
      + +

      +The Fortran function shifts the num by 1 because of 1-based +indexing. +

      + +
      +
      qmckl_exit_code qmckl_set_single_point_f (qmckl_context context,
      +                                 const char transp,
      +                                 const int64_t num,
      +                                 const double* coord,
      +                                 const int64_t size_max);
      +
      +
      + + + +
      +
      qmckl_exit_code
      +qmckl_set_single_point (qmckl_context context,
      +                 const char transp,
      +                 const int64_t num,
      +                 const double* coord,
      +                 const int64_t size_max)
      +{
      +
      +  if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
      +    return QMCKL_NULL_CONTEXT;
      +  }
      +
      +  if (num < 0) {
      +      return qmckl_failwith( context,
      +                             QMCKL_INVALID_ARG_3,
      +                             "qmckl_set_single_point",
      +                             "Incorrect point number");
      +  }
      +
      +  if (transp != 'N' && transp != 'T') {
      +    return qmckl_failwith( context,
      +                           QMCKL_INVALID_ARG_2,
      +                           "qmckl_set_single_point",
      +                           "transp should be 'N' or 'T'");
      +  }
      +
      +  if (coord == NULL) {
      +    return qmckl_failwith( context,
      +                           QMCKL_INVALID_ARG_3,
      +                           "qmckl_set_single_point",
      +                           "coord is a NULL pointer");
      +  }
      +
      +  qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
      +  assert (ctx != NULL);
      +
      +  int64_t walk_num = ctx->electron.walker.num;
      +
      +  if (size_max < 3*walk_num) {
      +      return qmckl_failwith( context,
      +                             QMCKL_INVALID_ARG_4,
      +                             "qmckl_set_single_point",
      +                             "Array too small");
      +  }
      +
      +  //qmckl_exit_code rc;
      +
      +  //if (ctx->single_point.coord.data != NULL) {
      +  //  rc = qmckl_matrix_free(context, &(ctx->single_point.coord));
      +  //  assert (rc == QMCKL_SUCCESS);
      +  //}
      +
      +  if (ctx->single_point.coord.data == NULL) {
      +    ctx->single_point.coord = qmckl_matrix_alloc(context, walk_num, 3);
      +    if (ctx->single_point.coord.data == NULL) {
      +      return qmckl_failwith( context,
      +                            QMCKL_ALLOCATION_FAILED,
      +                            "qmckl_set_single_point",
      +                            NULL);
      +    }
      +  }
      +
      +  ctx->single_point.num = num;
      +
      +  if (transp == 'N') {
      +    double *a = ctx->single_point.coord.data;
      +    for (int64_t i=0 ; i<3*walk_num ; ++i) {
      +      a[i] = coord[i];
      +    }
      +  } else {
      +    for (int64_t i=0 ; i<walk_num ; ++i) {
      +      qmckl_mat(ctx->single_point.coord, i, 0) = coord[i*walk_num + 0];
      +      qmckl_mat(ctx->single_point.coord, i, 1) = coord[i*walk_num + 1];
      +      qmckl_mat(ctx->single_point.coord, i, 2) = coord[i*walk_num + 2];
      +    }
      +  }
      +
      +  /* Increment the date of the single point */
      +  ctx->single_point.date += 1UL;
      +
      +  return QMCKL_SUCCESS;
      +
      +}
      +
      +qmckl_exit_code
      +qmckl_set_single_point_f (qmckl_context context,
      +                 const char transp,
      +                 const int64_t num,
      +                 const double* coord,
      +                 const int64_t size_max)
      +{
      +  return qmckl_set_single_point(context, transp, num-1, coord, size_max);
      +}
      +
      +
      + +
      +
      interface
      +  integer(qmckl_exit_code) function qmckl_set_single_point(context, &
      +       transp, num, coord, size_max) bind(C, name="qmckl_set_single_point_f")
      +    use, intrinsic :: iso_c_binding
      +    import
      +    implicit none
      +
      +    integer (c_int64_t) , intent(in)  , value :: context
      +    character(c_char)   , intent(in)  , value :: transp
      +    integer (c_int64_t) , intent(in)  , value :: num
      +    real    (c_double ) , intent(in)          :: coord(*)
      +    integer (c_int64_t) , intent(in)  , value :: size_max
      +  end function
      +end interface
      +
      +
      +
      +
      + +
      +

      3.2. Touch

      +
      +
      +
      qmckl_exit_code
      +qmckl_single_touch (const qmckl_context context);
      +
      +
      +
      +
      +
      + + +
      +

      4. Electron-electron and electron-nucleus distances for single point

      +
      +

      +In order to calculate the \(\delta J\), the updated electron-electron and electron-nucleus distances are required. +

      +
      + +
      +

      4.1. Electron-electron distances

      +
      +

      +Electron-electron distance between the single electron and all +electrons for all walkers. +Dimension is [walk_num][elec_num]. +

      +
      + +
      +

      4.1.1. Get

      +
      +
      +
      qmckl_exit_code qmckl_get_single_electron_ee_distance(qmckl_context context,
      +                                                      double* const distance,
      +                                                      const int64_t size_max);
      +
      +
      +
      +
      + +
      +

      4.1.2. Compute

      +
      +
    + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    elec_numint64_tinNumber of electrons
    walk_numint64_tinNumber of walkers
    coorddouble[3][walk_num][elec_num]inElectron coordinates
    single_coorddouble[walk_num][3]inSingle electron coordinates
    single_ee_distancedouble[walk_num][elec_num]outElectron-electron distances for single electron
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_single_ee_distance(context, &
    +     num_in, elec_num, walk_num, coord, single_coord, single_ee_distance) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer (c_int64_t) , intent(in)  , value :: elec_num, num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  real    (c_double ) , intent(in)          :: coord(elec_num,walk_num,3)
    +  real    (c_double ) , intent(in)          :: single_coord(3,walk_num)
    +  real    (c_double ) , intent(out)         :: single_ee_distance(elec_num,walk_num)
    +
    +  integer*8 :: k, i, j, num
    +  double precision :: x, y, z
    +
    +  info = QMCKL_SUCCESS
    +
    +  num = num_in + 1
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  do k=1,walk_num
    +     info = qmckl_distance(context, 'T', 'N', elec_num, 1_8, &
    +          coord(1,k,1), elec_num*walk_num, &
    +          single_coord(1,k), 3_8, &
    +          single_ee_distance(1,k), elec_num)
    +     if (info /= QMCKL_SUCCESS) then
    +        exit
    +     endif
    +     single_ee_distance(num,k) = 0.0d0
    +  end do
    +
    +
    +
    +end function qmckl_compute_single_ee_distance
    +
    +
    +
    +
    +
    + +
    +

    4.2. Electron-nucleus distances

    +
    +

    +Electron-nucleus distance between the single electron and all +nuclei for all walkers. +Dimension is [walk_num][nucl_num]. +

    +
    + +
    +

    4.2.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_single_electron_en_distance(qmckl_context context,
    +                                      double* distance,
    +                                      const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    4.2.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    nucl_numint64_tinNumber of nuclei
    walk_numint64_tinNumber of walkers
    elec_coorddouble[3][walk_num]inElectron coordinates
    nucl_coorddouble[3][nucl_num]inNuclear coordinates
    single_en_distancedouble[walk_num][nucl_num]outElectron-nucleus distances for single-electron
    + +
    +
    integer function qmckl_compute_single_en_distance(context, nucl_num, walk_num,  &
    +     elec_coord, nucl_coord, single_en_distance) result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)        :: context
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num, walk_num
    +  real    (c_double ) , intent(in)          :: elec_coord(3,walk_num)
    +  real    (c_double ) , intent(in)          :: nucl_coord(nucl_num,3)
    +  real    (c_double ) , intent(out)         :: single_en_distance(nucl_num, walk_num)
    +
    +  integer*8 :: k
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  info = qmckl_distance(context, 'T', 'N', nucl_num, walk_num, &
    +          nucl_coord, nucl_num, &
    +          elec_coord, 3_8, &
    +          single_en_distance, nucl_num)
    +
    +end function qmckl_compute_single_en_distance
    +
    +
    +
    +
    +
    +
    + +
    +

    5. Electron-electron-nucleus Jastrow

    +
    +

    +Calcules the single electron contributions to the electron-electron-nucleus Jastrow term. +First, the rescaled distances for the single electron electron-nucleus and electron-electron distances are computed. +These rescaled distances can be calculates by +\[ +\widetilde{R}_{i\alpha} = e^{-\kappa l R_{i\alpha}} \quad \text{and} \quad \widetilde{r}_{ij} = e^{-\kappa l r_{ij}}. +\] +Here, \(\kappa\) is the rescaling factor and \(l\) the power. The neccessery powers are stored in the same array. +From these, we can calculate the \(\delta \widetilde{R}\) and \(\delta \widetilde{r}\) using +

    +\begin{eqnarray*} +\delta \widetilde{R}_{i\alpha} &=& \widetilde{R}_{i\alpha}^\text{new} - \widetilde{R}_{i\alpha}^\text{old} \quad \text{and}\\ +\delta \widetilde{r}_{ij} &=& \widetilde{r}_{ij}^\text{new} - \widetilde{r}_{ij}^\text{old}. +\end{eqnarray*} + + +

    +With these, we can now calculate the single electron contribution to the \(\delta P\) matrix, using the equation +

    +\begin{eqnarray*} +\delta P_{i,\alpha,k,l} &=& P^{\text{new}}_{i,\alpha,k,l} - P^{\text{old}}_{i,\alpha,k,l}\\ +&=& \sum_{j=1}^{N_\text{elec}} \left(\widetilde{r}_{i,j,k} \delta \widetilde{R}_{j,\alpha,l}\delta_{j,\text{num}} + +\delta \widetilde{r}_{i,j,k} \widetilde{R}_{j,\alpha,l} (\delta_{j,\text{num}} ++ \delta_{i,\text{num}}) + \delta \widetilde{r}_{i,j,k} \delta \widetilde{R}_{j,\alpha,l} \delta_{j,\text{num}}\right)\\ +&=& \sum_{j=1}^{N_\text{elec}} \left( \delta \widetilde{r}_{i,j,k} \widetilde{R}_{j,\alpha,l} \delta_{i,\text{num}} \right) ++ \widetilde{r}_{i,\text{num},k} \delta \widetilde{R}_{\text{num},\alpha,l} + \delta \widetilde{r}_{i,\text{num},k} \left( \widetilde{R}_{\text{num},\alpha,l} ++ \delta \widetilde{R}_{\text{num},\alpha,l} \right). +\end{eqnarray*} + +

    +Then, the electron-electron-nucleus Jastrow value can be calculated by +

    +\begin{eqnarray*} +\delta J_{een} &=& J_{een}^{\text{new}} - J_{een}^{\text{old}}\\ +&=&\sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}}\sum_{\alpha=1}^{N_\text{nucl}} c_{l,k,p,\alpha} +\sum_{i=1}^{N_\text{elec}} \left( \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} P_{i,\alpha,k,(p-k+l)/2} \delta_{i,\text{num}} ++ \widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} \delta_{i,\text{num}} \right)\\ +&=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}}\sum_{\alpha=1}^{N_\text{nucl}} c_{l,k,p,\alpha} \left( +\sum_{i=1}^{N_\text{elec}} \left( \widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(P_{\text{num},\alpha,k,(p-k+l)/2} + \delta P_{\text{num},\alpha,k,(p-k+l)/2} \right)\right) +\end{eqnarray*} + + +

    +To calculate the gradients and Laplacian of the electron-electron-nucleus Jastrow, +we first have to calculate the gradients and Laplacian of the rescaled distances, +\[ +\partial_{i,m} \widetilde{R}_{i\alpha} = -\kappa l e^{-\kappa l R_{i\alpha}} \frac{r_{i,m} - R_{\alpha,m}}{R_{i\alpha}} \quad \text{and} \quad +\partial_{i,4} \widetilde{R}_{i\alpha} = -\kappa l \left(\frac{2}{R_{i\alpha}}- \kappa l \right) e^{-\kappa l R_{i\alpha}}, +\] +where \(i\) is the electron of which we are taking the derivative and \(m=1:3\) are the gradients and \(m=4\) is the Laplacian. +The derivatives of the single electron rescaled electron-nucleus distances are only nonzero when \(i=\text{num}\). +Similarly for \(r\) we get +\[ +\partial_{i,m} \widetilde{r}_{ij} = -\kappa l e^{-\kappa l r_{ij}} \frac{r_{i,m} - r_{j,m}}{r_{ij}} \quad \text{and} \quad +\partial_{i,4} \widetilde{r}_{ij} = -\kappa l \left(\frac{2}{r_{ij}}- \kappa l \right) e^{-\kappa l r_{ij}}. +\] +

    + +

    +With these, we can now calculate the gradient and Laplacian of the \(\delta P\) matrix, using the equation +

    +\begin{eqnarray*} +\partial_{i,m} \delta P_{i,\alpha,k,l} &=& \partial_{i,m} P_{i,\alpha,k,l}^\text{new} - \partial_{i,m} P_{i,\alpha,k,l}^\text{old}\\ +&=& \partial_{i,m}\delta \widetilde{r}_{\text{num},i,k} \left(\partial_{i,m}\delta \widetilde{R}_{\text{num},\alpha,l} + \partial_{i,m}\widetilde{R}_{\text{num},\alpha,l} \right) g_m ++ \partial_{i,m}\widetilde{r}_{\text{num},i,k} \delta \widetilde{R}_{\text{num},\alpha,l} ++ \delta_{i,\text{num}} \sum_{j=1}^{N_\text{elec}} \left( \partial_{j,m} \delta \widetilde{r}_{\text{num},j,k} \widetilde{R}_{j,\alpha,l} \right), +\end{eqnarray*} +

    +where \(g_m = \{-1,-1,-1,1\}\). +

    + +

    +Then, the gradient and Laplacian of the electron-electron-nucleus Jastrow value can be calculated by +

    +\begin{eqnarray*} +\delta \partial_{i,m} J_{een} &=& \partial_{i,m} J_{een}^{\text{new}} - \partial_{i,m} J_{een}^{\text{old}}\\ +&=&\sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}}\sum_{\alpha=1}^{N_\text{nucl}} c_{l,k,p,\alpha} +\left( \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{i,m} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \widetilde{R}_{i,\alpha,(p-k+l)/2} \partial_{i,m} \delta P_{i,\alpha,k,(p-k-l)/2} \right. \\ +& &\ + \partial_{i,m}\widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \partial_{i,m}\widetilde{R}_{i,\alpha,(p-k+l)/2} \delta P_{i,\alpha,k,(p-k-l)/2} \\ +& &\ + \delta_{i,\text{num}} \left( \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left ( \partial_{i,m} P_{i,\alpha,k,(p-k+l)/2} + \partial_{i,m} \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left ( \partial_{i,m} P_{i,\alpha,k,(p-k-l)/2} + \partial_{i,m} \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right. \\ +& &\ \left. + \partial_{i,m} \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left ( P_{i,\alpha,k,(p-k+l)/2} + \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \partial_{i,m} \delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left ( P_{i,\alpha,k,(p-k-l)/2} + \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right)\\ +& &\ + \delta_{m,4} \sum_{d=1}^3 \left( \partial_{i,d} \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{i,d} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \partial_{i,d} \widetilde{R}_{i,\alpha,(p-k+l)/2} \partial_{i,d} \delta P_{i,\alpha,k,(p-k-l)/2} \right)\\ +& &\ \left. + \delta_{m,4}\delta_{i,\text{num}} \sum_{d=1}^3\left( \partial_{i,d}\delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left( \partial_{i,d} P_{i,\alpha,k,(p-k+l)/2} + \partial_{i,d}\delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \partial_{i,d}\delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left( \partial_{i,d} P_{i,\alpha,k,(p-k-l)/2} + \partial_{i,d} \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right) \right) +\end{eqnarray*} +
    + +
    +

    5.1. Electron-electron rescaled distances

    +
    +

    +Computes the new components of the \(\widetilde{r}_{ij}\) matrix. Because only one electron is moved, the new matrix only has one dimension of size elec_num. +

    +
    + +
    +

    5.1.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_een_rescaled_single_e(qmckl_context context,
    +                                 double* const distance_rescaled,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.1.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinNumber of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    cord_numint64_tinOrder of polynomials
    rescale_factor_eedoubleinFactor to rescale ee distances
    single_ee_distancedouble[walk_num][elec_num]inSingle electron-electron distances for each walker
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inRescaled electron-electron distances for each walker
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]outSingle electron-electron rescaled distances for each walker
    + +
    +
    integer function qmckl_compute_een_rescaled_single_e_doc( &
    +     context, num_in, walk_num, elec_num, cord_num, rescale_factor_ee,  &
    +     single_ee_distance, een_rescaled_e, een_rescaled_single_e) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)         :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in
    +  integer(c_int64_t)    , intent(in), value  :: walk_num
    +  integer(c_int64_t)    , intent(in), value  :: elec_num
    +  integer(c_int64_t)    , intent(in), value  :: cord_num
    +  real(c_double)        , intent(in), value  :: rescale_factor_ee
    +  real(c_double)        , intent(in)         :: single_ee_distance(elec_num,walk_num)
    +  real(c_double)        , intent(in)         :: een_rescaled_e(elec_num,elec_num,0:cord_num,walk_num)
    +  real(c_double)        , intent(out)        :: een_rescaled_single_e(elec_num,0:cord_num,walk_num)
    +
    +  double precision,allocatable        :: een_rescaled_single_e_ij(:,:)
    +  double precision                    :: x
    +  integer*8                           :: i, j, k, l, nw, num
    +
    +  num = num_in + 1
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (cord_num < 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  allocate(een_rescaled_single_e_ij(elec_num, cord_num + 1))
    +
    +  ! Prepare table of exponentiated distances raised to appropriate power
    +  do nw = 1, walk_num
    +     een_rescaled_single_e_ij(:, 1) = 1.0d0
    +
    +
    +     do j = 1, elec_num
    +        een_rescaled_single_e_ij(j, 2) = dexp(-rescale_factor_ee * single_ee_distance(j, nw))
    +     end do
    +
    +
    +     do l = 2, cord_num
    +        do k = 1, elec_num
    +           een_rescaled_single_e_ij(k, l + 1) = een_rescaled_single_e_ij(k, l) * een_rescaled_single_e_ij(k, 2)
    +        end do
    +     end do
    +
    +     ! prepare the actual een table
    +     een_rescaled_single_e(:,0,nw) = 1.0d0
    +
    +     do l = 1, cord_num
    +        do j = 1, elec_num
    +            x = een_rescaled_single_e_ij(j, l + 1)
    +            een_rescaled_single_e(j, l, nw) = x
    +        end do
    +     end do
    +
    +     een_rescaled_single_e(num, :, :) = 0.0d0
    +
    +  end do
    +
    +end function qmckl_compute_een_rescaled_single_e_doc
    +
    +
    +
    +
    +
    + + + +
    +

    5.2. Electron-nucleus rescaled distances

    +
    +

    +Computes the new components of the \(\widetilde{R}_{i\alpha}\) matrix. +

    +
    + +
    +

    5.2.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_een_rescaled_single_n(qmckl_context context,
    +                                 double* const distance_rescaled,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.2.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinNumber of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of atoms
    nucl_numint64_tinNumber of atoms
    type_nucl_numint64_tinNumber of atom types
    type_nucl_vectorint64_t[nucl_num]inTypes of atoms
    cord_numint64_tinOrder of polynomials
    rescale_factor_endouble[nucl_num]inFactor to rescale ee distances
    single_en_distancedouble[walk_num][nucl_num]inElectron-nucleus distances
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]outSingle electron-nucleus rescaled distances
    + +
    +
    integer function qmckl_compute_een_rescaled_single_n( &
    +     context, num_in, walk_num, elec_num, nucl_num, &
    +     type_nucl_num, type_nucl_vector, cord_num, rescale_factor_en,  &
    +     single_en_distance, een_rescaled_n, een_rescaled_single_n) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in
    +  integer(c_int64_t)    , intent(in), value  :: walk_num
    +  integer(c_int64_t)    , intent(in), value  :: elec_num
    +  integer(c_int64_t)    , intent(in), value  :: nucl_num
    +  integer(c_int64_t)    , intent(in), value  :: type_nucl_num
    +  integer(c_int64_t)    , intent(in)         :: type_nucl_vector(nucl_num)
    +  integer(c_int64_t)    , intent(in), value  :: cord_num
    +  real(c_double)        , intent(in)         :: rescale_factor_en(type_nucl_num)
    +  real(c_double)        , intent(in)         :: single_en_distance(nucl_num,walk_num)
    +  real(c_double)        , intent(in)         :: een_rescaled_n(elec_num,nucl_num,0:cord_num,walk_num)
    +  real(c_double)        , intent(out)        :: een_rescaled_single_n(nucl_num,0:cord_num,walk_num)
    +
    +  double precision                    :: x
    +  integer*8                           :: i, a, k, l, nw, num
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (cord_num < 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  do nw = 1, walk_num
    +
    +     ! prepare the actual een table
    +     een_rescaled_single_n(:, 0, nw) = 1.0d0
    +
    +     do a = 1, nucl_num
    +        een_rescaled_single_n(a, 1, nw) = dexp(-rescale_factor_en(type_nucl_vector(a)+1) * single_en_distance(a, nw))
    +     end do
    +
    +     do l = 2, cord_num
    +        do a = 1, nucl_num
    +           een_rescaled_single_n(a, l, nw) = een_rescaled_single_n(a, l - 1, nw) * een_rescaled_single_n(a, 1, nw)
    +        end do
    +     end do
    +
    +  end do
    +
    +end function qmckl_compute_een_rescaled_single_n
    +
    +
    +
    +
    +
    + +
    +

    5.3. \(\delta P\) matrix

    +
    +

    +Computes the \(\delta P\) matrix. +

    +\begin{eqnarray*} +\delta P_{i,\alpha,k,l} = \sum_{j=1}^{N_\text{elec}} \left( \delta \widetilde{r}_{i,j,k} \widetilde{R}_{j,\alpha,l} \delta_{i,\text{num}} \right) ++ \widetilde{r}_{i,\text{num},k} \delta \widetilde{R}_{\text{num},\alpha,l} + \delta \widetilde{r}_{i,\text{num},k} \left( \widetilde{R}_{\text{num},\alpha,l} ++ \delta \widetilde{R}_{\text{num},\alpha,l} \right). +\end{eqnarray*} +
    + +
    +

    5.3.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_delta_p(qmckl_context context,
    +                                 double* const delta_p,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.3.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinSingle point index
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-electron rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron single rescaled distances
    delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]outDelta P matrix
    + +
    +
    integer function qmckl_compute_jastrow_champ_delta_p_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     een_rescaled_n, een_rescaled_e, een_rescaled_single_n, een_rescaled_single_e, delta_p) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t), intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num
    +  real(c_double) , intent(in)            :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double) , intent(in)            :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double) , intent(in)            :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double) , intent(in)            :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double) , intent(out)           :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: een_rescaled_delta_e(elec_num)
    +
    +  integer*8 :: i, a, c, j, l, k, p, m, n, nw, num
    +  double precision :: dn, dn2
    +  integer*8                           :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  if (cord_num == 0) return
    +
    +  do nw=1, walk_num
    +
    +     do i=0, cord_num-1
    +
    +        een_rescaled_delta_e(:) = een_rescaled_single_e(:,i,nw) - een_rescaled_e(:,num,i,nw)
    +
    +        do c=0,cord_num
    +           do a=1,nucl_num
    +              dn = een_rescaled_single_n(a,c,nw) - een_rescaled_n(num,a,c,nw)
    +              dn2 = een_rescaled_single_n(a,c,nw)
    +              do j=1,elec_num
    +                 delta_p(j,a,c,i,nw) = een_rescaled_e(j,num,i,nw)*dn + een_rescaled_delta_e(j) * dn2
    +              enddo
    +           end do
    +        end do
    +
    +        info = qmckl_dgemm(context, 'T', 'N', 1_8, nucl_num * (cord_num+1_8), elec_num, 1.0d0,     &
    +             een_rescaled_delta_e,elec_num, &
    +             een_rescaled_n(1,1,0,nw),elec_num,     &
    +             1.0d0,                                 &
    +             delta_p(num,1,0,i,nw),elec_num)
    +
    +     enddo
    +
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_delta_p_doc
    +
    +
    +
    +
    +
    + +
    +

    5.4. Electron-electron-nucleus Jastrow value

    +
    +

    +Computes \(\delta J_{een}\) by combining \(\delta \widetilde{R}_{i\alpha}\) and \(\delta P\). +

    +\begin{eqnarray*} +J_{een} = \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}}\sum_{\alpha=1}^{N_\text{nucl}} c_{l,k,p,\alpha} \left( +\sum_{i=1}^{N_\text{elec}} \left( \widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{\text{num},\alpha,(p-k-l)/2} \left(P_{\text{num},\alpha,k,(p-k+l)/2} + \delta P_{\text{num},\alpha,k,(p-k+l)/2} \right)\right) +\end{eqnarray*} +
    + +
    +

    5.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_een(qmckl_context context,
    +                                 double* const delta_een,
    +                                 const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_een (context, &
    +        delta_een, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_een(size_max)
    +   end function
    +end interface
    +
    +
    +
    +
    + +
    +

    5.4.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinSingle point number
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inDelta P matrix
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-electron rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron single rescaled distances
    delta_eendouble[walk_num]outSingle electron electron-electron-nucleus Jastrow
    + +
    +
    integer function qmckl_compute_jastrow_champ_factor_single_een_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     tmp_c, delta_p, een_rescaled_n, een_rescaled_e, een_rescaled_single_n, &
    +     een_rescaled_single_e, delta_een) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer(c_int64_t)    , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real(c_double)        , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real(c_double)        , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out) :: delta_een(walk_num)
    +
    +  double precision        :: delta_c(nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  double precision        :: delta_c2(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: een_rescaled_delta_n(nucl_num, 0:cord_num)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num
    +  double precision :: accu, accu2, cn
    +  integer*8                           :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  delta_een = 0.0d0
    +
    +  if (cord_num == 0) return
    +
    +  do nw =1, walk_num
    +     een_rescaled_delta_n(:,:) = een_rescaled_single_n(:,:,nw) - een_rescaled_n(num,:,:,nw)
    +     do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        p = lkpm_combined_index(n, 3)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do a = 1, nucl_num
    +           cn = c_vector_full(a, n)
    +           if(cn == 0.d0) cycle
    +
    +           accu = 0.0d0
    +           do j = 1, elec_num
    +              accu = accu + een_rescaled_n(j,a,m,nw) * delta_p(j,a,m+l,k,nw)
    +           end do
    +           accu = accu + een_rescaled_delta_n(a,m) * (tmp_c(num,a,m+l,k,nw) + delta_p(num,a,m+l,k,nw))
    +           delta_een(nw) = delta_een(nw) + accu * cn
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_factor_single_een_doc
    +
    +
    +
    +
    +
    + +
    +

    5.5. Electron-nucleus rescaled distance derivative

    +
    +

    +Calculates \(\partial_{i,m} \widetilde{R}_{i,\alpha}\), which is required to compute the derivative of \(J_{een}\). +\[ +\partial_{i,m} \widetilde{R}_{i\alpha} = -\kappa l e^{-\kappa l R_{i\alpha}} \frac{r_{i,m} - R_{\alpha,m}}{R_{i\alpha}} \quad \text{and} \quad +\partial_{i,4} \widetilde{R}_{i\alpha} = -\kappa l \left(\frac{2}{R_{i\alpha}}- \kappa l \right) e^{-\kappa l R_{i\alpha}}, +\] +

    +
    + +
    +

    5.5.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_een_rescaled_single_n_gl(qmckl_context context,
    +                                         double* const distance_rescaled,
    +                                         const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.5.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    walk_numint64_tinNumber of walkers
    nucl_numint64_tinNumber of atoms
    type_nucl_numint64_tinNumber of atom types
    type_nucl_vectorint64_t[nucl_num]inTypes of atoms
    cord_numint64_tinOrder of polynomials
    rescale_factor_endouble[nucl_num]inFactor to rescale ee distances
    coord_eedouble[walk_num][3]inElectron coordinates
    coord_ndouble[3][nucl_num]inNuclear coordinates
    single_en_distancedouble[walk_num][nucl_num]inElectron-nucleus single distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus rescaled single distances
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]outElectron-nucleus rescaled single distances derivative
    + +
    +
    integer function qmckl_compute_een_rescaled_single_n_gl( &
    +     context, walk_num, nucl_num, type_nucl_num, type_nucl_vector, &
    +     cord_num, rescale_factor_en, coord_ee, coord_n, single_en_distance, &
    +     een_rescaled_single_n, een_rescaled_single_n_gl) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in), value  :: context
    +  integer(c_int64_t)    , intent(in), value  :: walk_num
    +  integer(c_int64_t)    , intent(in), value  :: nucl_num
    +  integer(c_int64_t)    , intent(in), value  :: type_nucl_num
    +  integer(c_int64_t)    , intent(in)         :: type_nucl_vector(nucl_num)
    +  integer(c_int64_t)    , intent(in), value  :: cord_num
    +  real(c_double)        , intent(in)         :: rescale_factor_en(type_nucl_num)
    +  real(c_double)        , intent(in)         :: coord_ee(3,walk_num)
    +  real(c_double)        , intent(in)         :: coord_n(nucl_num,3)
    +  real(c_double)        , intent(in)         :: single_en_distance(nucl_num,walk_num)
    +  real(c_double)        , intent(in)         :: een_rescaled_single_n(nucl_num,0:cord_num,walk_num)
    +  real(c_double)        , intent(out)        :: een_rescaled_single_n_gl(4,nucl_num,0:cord_num,walk_num)
    +
    +  double precision,allocatable   :: elnuc_dist_gl(:,:)
    +  double precision               :: x, ria_inv, kappa_l
    +  integer*8                      :: i, a, k, l, nw, ii
    +
    +  allocate(elnuc_dist_gl(4, nucl_num))
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (cord_num < 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  ! Prepare table of exponentiated distances raised to appropriate power
    +  een_rescaled_single_n_gl             = 0.0d0
    +  do nw = 1, walk_num
    +     ! prepare the actual een table
    +     do a = 1, nucl_num
    +        ria_inv = 1.0d0 / single_en_distance(a, nw)
    +        do ii = 1, 3
    +           elnuc_dist_gl(ii, a) = (coord_ee(ii,nw) - coord_n(a, ii)) * ria_inv
    +        end do
    +        elnuc_dist_gl(4, a) = 2.0d0 * ria_inv
    +     end do
    +
    +     do l = 0, cord_num
    +        do a = 1, nucl_num
    +           kappa_l = - dble(l) * rescale_factor_en(type_nucl_vector(a)+1)
    +           een_rescaled_single_n_gl(1, a, l, nw) = kappa_l * elnuc_dist_gl(1, a)
    +           een_rescaled_single_n_gl(2, a, l, nw) = kappa_l * elnuc_dist_gl(2, a)
    +           een_rescaled_single_n_gl(3, a, l, nw) = kappa_l * elnuc_dist_gl(3, a)
    +           een_rescaled_single_n_gl(4, a, l, nw) = kappa_l * (elnuc_dist_gl(4, a) + kappa_l)
    +
    +           een_rescaled_single_n_gl(1, a, l, nw) = een_rescaled_single_n_gl(1, a, l, nw) * &
    +                een_rescaled_single_n(a, l, nw)
    +           een_rescaled_single_n_gl(2, a, l, nw) = een_rescaled_single_n_gl(2, a, l, nw) * &
    +                een_rescaled_single_n(a, l, nw)
    +           een_rescaled_single_n_gl(3, a, l, nw) = een_rescaled_single_n_gl(3, a, l, nw) * &
    +                een_rescaled_single_n(a, l, nw)
    +           een_rescaled_single_n_gl(4, a, l, nw) = een_rescaled_single_n_gl(4, a, l, nw) * &
    +                een_rescaled_single_n(a, l, nw)
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_een_rescaled_single_n_gl
    +
    +
    +
    +
    +
    + +
    +

    5.6. Electron-electron rescaled distances derivative

    +
    +

    +Calculates the updated terms of \(\partial_{i,m} \widetilde{r}_{ij}\), required for computing the derivative of \(J_{een}\). +\[ +\partial_{i,m} \widetilde{r}_{ij} = -\kappa l e^{-\kappa l r_{ij}} \frac{r_{i,m} - r_{j,m}}{r_{ij}} \quad \text{and} \quad +\partial_{i,4} \widetilde{r}_{ij} = -\kappa l \left(\frac{2}{r_{ij}}- \kappa l \right) e^{-\kappa l r_{ij}}. +\] +

    +
    + + +
    +

    5.6.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_een_rescaled_single_e_gl(qmckl_context context,
    +                                         double* const distance_rescaled,
    +                                         const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.6.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    cord_numint64_tinOrder of polynomials
    rescale_factor_eedoubleinFactor to rescale ee distances
    coorddouble[walk_num][3]inSingle electron coordinates
    coord_eedouble[3][walk_num][elec_num]inElectron coordinates
    single_ee_distancedouble[walk_num][elec_num]inElectron-electron single distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron rescaled single distances
    een_rescaled_single_e_gldouble[walk_num][0:cord_num][elec_num][4]outElectron-electron rescaled single distances derivative
    + +
    +
    integer function qmckl_compute_een_rescaled_single_e_gl_doc( &
    +     context, num_in, walk_num, elec_num, cord_num, rescale_factor_ee,  &
    +     coord, coord_ee, single_ee_distance, een_rescaled_single_e, een_rescaled_single_e_gl) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)        :: context
    +  integer(c_int64_t)    , intent(in), value :: num_in
    +  integer(c_int64_t)    , intent(in), value :: walk_num
    +  integer(c_int64_t)    , intent(in), value :: elec_num
    +  integer(c_int64_t)    , intent(in), value :: cord_num
    +  real(c_double)        , intent(in), value :: rescale_factor_ee
    +  real(c_double)        , intent(in)        :: coord(3,walk_num)
    +  real(c_double)        , intent(in)        :: coord_ee(elec_num,walk_num,3)
    +  real(c_double)        , intent(in)        :: single_ee_distance(elec_num,walk_num)
    +  real(c_double)        , intent(in)        :: een_rescaled_single_e(elec_num,0:cord_num,walk_num)
    +  real(c_double)        , intent(out)       :: een_rescaled_single_e_gl(4,elec_num,0:cord_num,walk_num)
    +
    +  double precision,allocatable   :: elec_dist_gl(:,:)
    +  double precision               :: x, rij_inv, kappa_l
    +  integer*8                      :: i, j, k, l, nw, ii, num
    +
    +  num = num_in + 1
    +
    +  allocate(elec_dist_gl(4, elec_num))
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (cord_num < 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +  !   Not necessary: should be set to zero by qmckl_malloc
    +  !   een_rescaled_single_e_gl = 0.0d0
    +
    +  ! Prepare table of exponentiated distances raised to appropriate power
    +
    +  do nw = 1, walk_num
    +     do i = 1, elec_num
    +        if (i == num) cycle
    +        rij_inv = 1.0d0 / single_ee_distance(i, nw)
    +        do ii = 1, 3
    +           elec_dist_gl(ii, i) = (coord(ii, nw) - coord_ee(i, nw, ii)) * rij_inv
    +        end do
    +        elec_dist_gl(4, i) = 2.0d0 * rij_inv
    +     end do
    +
    +     elec_dist_gl(:, num) = 0.0d0
    +
    +     do l = 1, cord_num
    +        kappa_l = - dble(l) * rescale_factor_ee
    +        do i = 1, elec_num
    +           een_rescaled_single_e_gl(1, i, l, nw) = kappa_l * elec_dist_gl(1, i)
    +           een_rescaled_single_e_gl(2, i, l, nw) = kappa_l * elec_dist_gl(2, i)
    +           een_rescaled_single_e_gl(3, i, l, nw) = kappa_l * elec_dist_gl(3, i)
    +           een_rescaled_single_e_gl(4, i, l, nw) = kappa_l * (elec_dist_gl(4, i) + kappa_l)
    +
    +           een_rescaled_single_e_gl(1,i,l,nw) = een_rescaled_single_e_gl(1,i,l,nw) * een_rescaled_single_e(i,l,nw)
    +           een_rescaled_single_e_gl(2,i,l,nw) = een_rescaled_single_e_gl(2,i,l,nw) * een_rescaled_single_e(i,l,nw)
    +           een_rescaled_single_e_gl(3,i,l,nw) = een_rescaled_single_e_gl(3,i,l,nw) * een_rescaled_single_e(i,l,nw)
    +           een_rescaled_single_e_gl(4,i,l,nw) = een_rescaled_single_e_gl(4,i,l,nw) * een_rescaled_single_e(i,l,nw)
    +
    +        end do
    +     end do
    +  end do
    +
    +
    +
    +end function qmckl_compute_een_rescaled_single_e_gl_doc
    +
    +
    +
    +
    +
    + +
    +

    5.7. \(\delta P\) matrix gradients and Laplacian

    +
    +

    +Calculate \(\partial_{i,m} \delta P\). +

    +\begin{eqnarray*} +\partial_{i,m} \delta P_{i,\alpha,k,l} = \partial_{i,m}\delta \widetilde{r}_{\text{num},i,k} \left(\partial_{i,m}\delta \widetilde{R}_{\text{num},\alpha,l} + \partial_{i,m}\widetilde{R}_{\text{num},\alpha,l} \right) g_m ++ \partial_{i,m}\widetilde{r}_{\text{num},i,k} \delta \widetilde{R}_{\text{num},\alpha,l} ++ \delta_{i,\text{num}} \sum_{j=1}^{N_\text{elec}} \left( \partial_{j,m} \delta \widetilde{r}_{\text{num},j,k} \widetilde{R}_{j,\alpha,l} \right), +\end{eqnarray*} +

    +where \(g_m = \{-1,-1,-1,1\}\). +

    +
    + +
    +

    5.7.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_delta_p_gl(qmckl_context context,
    +                                 double* const delta_p_gl,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.7.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-electron rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_e_gldouble[walk_num][0:cord_num][elec_num][4][elec_num]inElectron-electron rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    een_rescaled_single_e_gldouble[walk_num][0:cord_num][elec_num][4]inElectron-electron single rescaled distances derivatives
    delta_p_gldouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][elec_num]outDelta P matrix gradient and Laplacian
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_jastrow_champ_delta_p_gl_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     een_rescaled_n, een_rescaled_e, een_rescaled_single_n, een_rescaled_single_e, &
    +     een_rescaled_n_gl, een_rescaled_e_gl, een_rescaled_single_n_gl, een_rescaled_single_e_gl, delta_p_gl) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e_gl(elec_num, 4, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e_gl(4,elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out)  :: delta_p_gl(elec_num,nucl_num,4,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: delta_e_gl(elec_num,4)
    +
    +  double precision        :: een_rescaled_delta_n, een_re_n, een_re_single_n
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num
    +  double precision :: tmp, cummu
    +  integer*8        :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +  if (cord_num == 0) then
    +     delta_p_gl = 0.d0
    +     return
    +  endif
    +
    +  do nw=1, walk_num
    +     do m=1, cord_num-1
    +        do k = 1, 4
    +          do j = 1, elec_num
    +            delta_e_gl(j,k) = een_rescaled_single_e_gl(k,j,m,nw) - een_rescaled_e_gl(num, k, j, m, nw)
    +          end do
    +        end do
    +        do k = 1, 4
    +          delta_e_gl(num, k) = 0.0d0
    +        end do
    +
    +        do l=0, cord_num
    +          do k = 1, 3
    +            do a = 1, nucl_num
    +
    +              een_re_n = een_rescaled_n(num, a, l, nw)
    +              een_re_single_n = een_rescaled_single_n(a,l,nw)
    +
    +              cummu = 0.0d0
    +              do i = 1, elec_num
    +
    +                delta_p_gl(i,a,k,l,m,nw) = -een_rescaled_e_gl(i,k,num,m,nw) * een_re_n &
    +                  - een_rescaled_single_e_gl(k,i,m,nw) * een_re_single_n
    +
    +                cummu = cummu + delta_e_gl(i,k) * een_rescaled_n(i,a,l,nw)
    +              end do
    +              delta_p_gl(num,a,k,l,m,nw) = delta_p_gl(num,a,k,l,m,nw) + cummu
    +
    +            end do
    +          end do
    +          do a = 1, nucl_num
    +            een_rescaled_delta_n = een_rescaled_single_n(a,l,nw) - een_rescaled_n(num, a, l, nw)
    +            cummu = 0.0d0
    +            een_re_single_n = een_rescaled_single_n(a,l,nw)
    +
    +            do i = 1, elec_num
    +              delta_p_gl(i,a,4,l,m,nw) = een_rescaled_e_gl(i,4,num,m,nw) * een_rescaled_delta_n &
    +                +delta_e_gl(i,4) * een_re_single_n
    +
    +              cummu = cummu + delta_e_gl(i,4) * een_rescaled_n(i,a,l,nw)
    +            end do
    +            delta_p_gl(num,a,4,l,m,nw) = delta_p_gl(num,a,4,l,m,nw) + cummu
    +
    +          end do
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_delta_p_gl_doc
    +
    +
    +
    +
    +
    + +
    +

    5.8. Electron-electron-nucleus Jastrow gradients and Laplacian

    +
    +

    +Calculates the gradients and Laplacian of \(\delta J_{een}\). +

    +\begin{eqnarray*} +\partial_{i,m} J_{een} &=& \sum_{p=2}^{N_\text{nord}} \sum_{k=0}^{p-1} \sum_{l=0}^{p-k-2\delta_{k,0}}\sum_{\alpha=1}^{N_\text{nucl}} c_{l,k,p,\alpha} +\left( \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{i,m} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \widetilde{R}_{i,\alpha,(p-k+l)/2} \partial_{i,m} \delta P_{i,\alpha,k,(p-k-l)/2} \right. \\ +& &\ + \partial_{i,m}\widetilde{R}_{i,\alpha,(p-k-l)/2} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \partial_{i,m}\widetilde{R}_{i,\alpha,(p-k+l)/2} \delta P_{i,\alpha,k,(p-k-l)/2} \\ +& &\ + \delta_{i,\text{num}} \left( \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left ( \partial_{i,m} P_{i,\alpha,k,(p-k+l)/2} + \partial_{i,m} \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left ( \partial_{i,m} P_{i,\alpha,k,(p-k-l)/2} + \partial_{i,m} \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right. \\ +& &\ \left. + \partial_{i,m} \delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left ( P_{i,\alpha,k,(p-k+l)/2} + \delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \partial_{i,m} \delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left ( P_{i,\alpha,k,(p-k-l)/2} + \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right)\\ +& &\ + \delta_{m,4} \sum_{d=1}^3 \left( \partial_{i,d} \widetilde{R}_{i,\alpha,(p-k-l)/2} \partial_{i,d} \delta P_{i,\alpha,k,(p-k+l)/2} ++ \partial_{i,d} \widetilde{R}_{i,\alpha,(p-k+l)/2} \partial_{i,d} \delta P_{i,\alpha,k,(p-k-l)/2} \right)\\ +& &\ \left. + \delta_{m,4}\delta_{i,\text{num}} \sum_{d=1}^3\left( \partial_{i,d}\delta \widetilde{R}_{i,\alpha,(p-k-l)/2} \left( \partial_{i,d} P_{i,\alpha,k,(p-k+l)/2} + \partial_{i,d}\delta P_{i,\alpha,k,(p-k+l)/2} \right) ++ \partial_{i,d}\delta \widetilde{R}_{i,\alpha,(p-k+l)/2} \left( \partial_{i,d} P_{i,\alpha,k,(p-k-l)/2} + \partial_{i,d} \delta P_{i,\alpha,k,(p-k-l)/2} \right) \right) \right) +\end{eqnarray*} +
    + + +
    +

    5.8.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_een_gl(qmckl_context context,
    +                                 double* const delta_een_gl,
    +                                 const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_een_gl (context, &
    +        delta_een_gl, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_een_gl(size_max)
    +   end function
    +end interface
    +
    +
    +
    +
    + +
    +

    5.8.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inP matrix derivative
    delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inDelta P matrix
    delta_p_gldouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][elec_num]inDelta P matrix derivative
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    delta_een_gldouble[walk_num][4][elec_num]outDelta electron-electron-nucleus jastrow gradient and Laplacian
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_jastrow_champ_factor_single_een_gl_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     tmp_c, dtmp_c, delta_p, delta_p_gl, een_rescaled_n, een_rescaled_single_n, &
    +     een_rescaled_n_gl, een_rescaled_single_n_gl, delta_een_gl) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer(c_int64_t)    , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real(c_double)        , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real(c_double)        , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: dtmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: delta_p_gl(elec_num, nucl_num, 4, 0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out) :: delta_een_gl(elec_num, 4, walk_num)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, kk, num
    +  double precision :: accu, accu2, cn
    +  integer*8                           :: LDA, LDB, LDC
    +
    +  double precision  :: een_rescaled_delta_n(nucl_num, 0:cord_num)
    +  double precision  :: een_rescaled_delta_n_gl(4, nucl_num, 0:cord_num)
    +  double precision :: dpg1_m, dpg1_ml, dp_m, dp_ml, een_r_m, een_r_ml, een_r_gl_m, een_r_gl_ml
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  delta_een_gl = 0.0d0
    +
    +  if (cord_num == 0) return
    +
    +
    +  do nw =1, walk_num
    +
    +     een_rescaled_delta_n(:,:) = een_rescaled_single_n(:,:,nw) - een_rescaled_n(num, :, :, nw)
    +     een_rescaled_delta_n_gl(:,:,:) = een_rescaled_single_n_gl(:,:,:,nw) - een_rescaled_n_gl(num, :,:,:,nw)
    +
    +     do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        p = lkpm_combined_index(n, 3)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do kk = 1, 4
    +           do a = 1, nucl_num
    +              cn = c_vector_full(a, n)
    +              if(cn == 0.d0) cycle
    +              do i = 1, elec_num
    +                 delta_een_gl(i,kk,nw) = delta_een_gl(i,kk,nw) + ( &
    +                      delta_p_gl(i,a,kk,m  ,k,nw) * een_rescaled_n(i,a,m+l,nw) + &
    +                      delta_p_gl(i,a,kk,m+l,k,nw) * een_rescaled_n(i,a,m  ,nw) + &
    +                      delta_p(i,a,m  ,k,nw) * een_rescaled_n_gl(i,kk,a,m+l,nw) + &
    +                      delta_p(i,a,m+l,k,nw) * een_rescaled_n_gl(i,kk,a,m  ,nw) ) * cn
    +              end do
    +
    +              delta_een_gl(num,kk,nw) = delta_een_gl(num,kk,nw) + ( &
    +                   (dtmp_c(num,kk,a,m  ,k,nw) + delta_p_gl(num,a,kk,m  ,k,nw)) * een_rescaled_delta_n(a,m+l) + &
    +                   (dtmp_c(num,kk,a,m+l,k,nw) + delta_p_gl(num,a,kk,m+l,k,nw)) * een_rescaled_delta_n(a,m  ) + &
    +                   (tmp_c(num,a,m  ,k,nw) + delta_p(num,a,m  ,k,nw)) * een_rescaled_delta_n_gl(kk,a,m+l)  + &
    +                   (tmp_c(num,a,m+l,k,nw) + delta_p(num,a,m+l,k,nw)) * een_rescaled_delta_n_gl(kk,a,m  ) )* cn
    +           end do
    +        end do
    +        do a = 1, nucl_num
    +           cn = c_vector_full(a, n)
    +           if(cn == 0.d0) cycle
    +           cn = cn + cn
    +           do i = 1, elec_num
    +              delta_een_gl(i,4,nw) = delta_een_gl(i,4,nw) + ( &
    +                   delta_p_gl(i,a,1,m  ,k,nw) * een_rescaled_n_gl(i,1,a,m+l,nw) + &
    +                   delta_p_gl(i,a,1,m+l,k,nw) * een_rescaled_n_gl(i,1,a,m  ,nw) + &
    +                   delta_p_gl(i,a,2,m  ,k,nw) * een_rescaled_n_gl(i,2,a,m+l,nw) + &
    +                   delta_p_gl(i,a,2,m+l,k,nw) * een_rescaled_n_gl(i,2,a,m  ,nw) + &
    +                   delta_p_gl(i,a,3,m  ,k,nw) * een_rescaled_n_gl(i,3,a,m+l,nw) + &
    +                   delta_p_gl(i,a,3,m+l,k,nw) * een_rescaled_n_gl(i,3,a,m  ,nw) ) * cn
    +           end do
    +          delta_een_gl(num,4,nw) = delta_een_gl(num,4,nw) + ( &
    +               (delta_p_gl(num,a,1,m  ,k,nw) + dtmp_c(num,1,a,m  ,k,nw)) * een_rescaled_delta_n_gl(1,a,m+l) + &
    +               (delta_p_gl(num,a,1,m+l,k,nw) + dtmp_c(num,1,a,m+l,k,nw)) * een_rescaled_delta_n_gl(1,a,m  ) + &
    +               (delta_p_gl(num,a,2,m  ,k,nw) + dtmp_c(num,2,a,m  ,k,nw)) * een_rescaled_delta_n_gl(2,a,m+l) + &
    +               (delta_p_gl(num,a,2,m+l,k,nw) + dtmp_c(num,2,a,m+l,k,nw)) * een_rescaled_delta_n_gl(2,a,m  ) + &
    +               (delta_p_gl(num,a,3,m  ,k,nw) + dtmp_c(num,3,a,m  ,k,nw)) * een_rescaled_delta_n_gl(3,a,m+l) + &
    +               (delta_p_gl(num,a,3,m+l,k,nw) + dtmp_c(num,3,a,m+l,k,nw)) * een_rescaled_delta_n_gl(3,a,m  ) ) * cn
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_factor_single_een_gl_doc
    +
    +
    + +
    +
    qmckl_exit_code
    +qmckl_compute_jastrow_champ_factor_single_een_gl_hpc (const qmckl_context context,
    +                                                      const int64_t num,
    +                                                      const int64_t walk_num,
    +                                                      const int64_t elec_num,
    +                                                      const int64_t nucl_num,
    +                                                      const int64_t cord_num,
    +                                                      const int64_t dim_c_vector,
    +                                                      const double* restrict c_vector_full,
    +                                                      const int64_t* restrict lkpm_combined_index,
    +                                                      const double* restrict tmp_c,
    +                                                      const double* restrict dtmp_c,
    +                                                      const double* restrict delta_p,
    +                                                      const double* restrict delta_p_gl,
    +                                                      const double* restrict een_rescaled_n,
    +                                                      const double* restrict een_rescaled_single_n,
    +                                                      const double* restrict een_rescaled_n_gl,
    +                                                      const double* restrict een_rescaled_single_n_gl,
    +                                                      double* restrict const delta_een_gl )
    +{
    +
    +
    +  if (context == QMCKL_NULL_CONTEXT) return QMCKL_INVALID_CONTEXT;
    +  if (walk_num <= 0)                 return QMCKL_INVALID_ARG_3;
    +  if (elec_num <= 0)                 return QMCKL_INVALID_ARG_4;
    +  if (nucl_num <= 0)                 return QMCKL_INVALID_ARG_5;
    +  if (cord_num <  0)                 return QMCKL_INVALID_ARG_6;
    +
    +  if (cord_num == 0) {
    +    #pragma omp parallel for
    +    for (size_t i=0 ; i<walk_num*4*elec_num ; ++i) {
    +      delta_een_gl[i] = 0.;
    +    }
    +    return QMCKL_SUCCESS;
    +  }
    +
    +#ifdef HAVE_OPENMP
    +#pragma omp parallel for
    +#endif
    +  for (int64_t nw=0 ; nw<walk_num ; nw++) {
    +    for (int64_t i=0 ; i<4*elec_num ; ++i) {
    +      delta_een_gl[i+nw*4*elec_num] = 0.;
    +    }
    +    double een_rescaled_delta_n[nucl_num*(cord_num+1)];
    +    double een_rescaled_delta_n_gl[4*nucl_num*(cord_num+1)];
    +    for (int64_t k=0 ; k<nucl_num*(cord_num+1) ; ++k) {
    +      een_rescaled_delta_n[k] = een_rescaled_single_n[k+nucl_num*(cord_num+1)*nw] - een_rescaled_n[num+elec_num*(k+nucl_num*(cord_num+1)*nw)];
    +      een_rescaled_delta_n_gl[0+4*k] = een_rescaled_single_n_gl[0+4*(k+nucl_num*(cord_num+1)*nw)] - een_rescaled_n_gl[num+elec_num*(0+4*(k+nucl_num*(cord_num+1)*nw))];
    +      een_rescaled_delta_n_gl[1+4*k] = een_rescaled_single_n_gl[1+4*(k+nucl_num*(cord_num+1)*nw)] - een_rescaled_n_gl[num+elec_num*(1+4*(k+nucl_num*(cord_num+1)*nw))];
    +      een_rescaled_delta_n_gl[2+4*k] = een_rescaled_single_n_gl[2+4*(k+nucl_num*(cord_num+1)*nw)] - een_rescaled_n_gl[num+elec_num*(2+4*(k+nucl_num*(cord_num+1)*nw))];
    +      een_rescaled_delta_n_gl[3+4*k] = een_rescaled_single_n_gl[3+4*(k+nucl_num*(cord_num+1)*nw)] - een_rescaled_n_gl[num+elec_num*(3+4*(k+nucl_num*(cord_num+1)*nw))];
    +    }
    +
    +    for (int64_t n=0 ; n<dim_c_vector ; ++n) {
    +      const int64_t l = lkpm_combined_index[n];
    +      const int64_t k = lkpm_combined_index[n+dim_c_vector];
    +      const int64_t m = lkpm_combined_index[n+3*dim_c_vector];
    +
    +      for (int64_t kk=0 ; kk<4 ; ++kk) {
    +        double* restrict dgl = &delta_een_gl[elec_num*(kk+4*nw)];
    +
    +        for (int64_t a=0 ; a<nucl_num ; ++a) {
    +          const double cn = c_vector_full[a+n*nucl_num];
    +          if (cn == 0.) continue;
    +
    +          const double* restrict dpg1_m    = &delta_p_gl[elec_num*(a+nucl_num*(kk+4*(m+(cord_num+1)*(k+cord_num*nw))))];
    +          const double* restrict dpg1_ml   = &delta_p_gl[elec_num*(a+nucl_num*(kk+4*(m+l+(cord_num+1)*(k+cord_num*nw))))];
    +          const double* restrict dp_m      = &delta_p[elec_num*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw)))];
    +          const double* restrict dp_ml     = &delta_p[elec_num*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw)))];
    +          const double* restrict een_r_m   = &een_rescaled_n[elec_num*(a+nucl_num*(m+(cord_num+1)*nw))];
    +          const double* restrict een_r_ml  = &een_rescaled_n[elec_num*(a+nucl_num*(m+l+(cord_num+1)*nw))];
    +          const double* restrict een_r_gl_m  = &een_rescaled_n_gl[elec_num*(kk+4*(a+nucl_num*(m+(cord_num+1)*nw)))];
    +          const double* restrict een_r_gl_ml = &een_rescaled_n_gl[elec_num*(kk+4*(a+nucl_num*(m+l+(cord_num+1)*nw)))];
    +
    +#ifdef HAVE_OPENMP
    +          #pragma omp simd
    +#endif
    +          for (int64_t i=0 ; i<elec_num ; ++i) {
    +            dgl[i] += cn * (dpg1_m[i] * een_r_ml[i] + dpg1_ml[i] * een_r_m[i] +
    +                            dp_m[i] * een_r_gl_ml[i] + dp_ml[i] * een_r_gl_m[i]);
    +          }
    +          dgl[num] += ( (dtmp_c[num+elec_num*(kk+4*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw))))] +
    +                         dpg1_m[num]
    +                         ) * een_rescaled_delta_n[a+nucl_num*(m+l)] +
    +                        (dtmp_c[num+elec_num*(kk+4*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw))))] +
    +                         dpg1_ml[num]
    +                         ) * een_rescaled_delta_n[a+nucl_num*m] +
    +                        (tmp_c[num+elec_num*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw)))] +
    +                         dp_m[num]
    +                         ) * een_rescaled_delta_n_gl[kk+4*(a+nucl_num*(m+l))] +
    +                        (tmp_c[num+elec_num*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw)))] +
    +                         dp_ml[num]
    +                         ) * een_rescaled_delta_n_gl[kk+4*(a+nucl_num*m)] 
    +                        ) * cn;
    +        }
    +      }
    +
    +      for (int a=0 ; a<nucl_num ; ++a) {
    +        const double cn = 2. * c_vector_full[a+n*nucl_num];
    +        if (cn == 0.) continue;
    +
    +        double* restrict dgl4 = &delta_een_gl[elec_num*(3+4*nw)];
    +
    +        const double* restrict dpg1_m    = &delta_p_gl[elec_num*(a+nucl_num*(0+4*(m+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict dpg2_m    = &delta_p_gl[elec_num*(a+nucl_num*(1+4*(m+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict dpg3_m    = &delta_p_gl[elec_num*(a+nucl_num*(2+4*(m+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict dpg1_ml   = &delta_p_gl[elec_num*(a+nucl_num*(0+4*(m+l+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict dpg2_ml   = &delta_p_gl[elec_num*(a+nucl_num*(1+4*(m+l+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict dpg3_ml   = &delta_p_gl[elec_num*(a+nucl_num*(2+4*(m+l+(cord_num+1)*(k+cord_num*nw))))];
    +        const double* restrict een_r_gl1_m  = &een_rescaled_n_gl[elec_num*(0+4*(a+nucl_num*(m+(cord_num+1)*nw)))];
    +        const double* restrict een_r_gl2_m  = &een_rescaled_n_gl[elec_num*(1+4*(a+nucl_num*(m+(cord_num+1)*nw)))];
    +        const double* restrict een_r_gl3_m  = &een_rescaled_n_gl[elec_num*(2+4*(a+nucl_num*(m+(cord_num+1)*nw)))];
    +        const double* restrict een_r_gl1_ml = &een_rescaled_n_gl[elec_num*(0+4*(a+nucl_num*(m+l+(cord_num+1)*nw)))];
    +        const double* restrict een_r_gl2_ml = &een_rescaled_n_gl[elec_num*(1+4*(a+nucl_num*(m+l+(cord_num+1)*nw)))];
    +        const double* restrict een_r_gl3_ml = &een_rescaled_n_gl[elec_num*(2+4*(a+nucl_num*(m+l+(cord_num+1)*nw)))];
    +
    +#ifdef HAVE_OPENMP
    +          #pragma omp simd
    +#endif
    +        for (int64_t i=0 ; i<elec_num ; ++i) {
    +          dgl4[i] += (dpg1_m[i] * een_r_gl1_ml[i] + dpg1_ml[i] * een_r_gl1_m[i] +
    +                      dpg2_m[i] * een_r_gl2_ml[i] + dpg2_ml[i] * een_r_gl2_m[i] +
    +                      dpg3_m[i] * een_r_gl3_ml[i] + dpg3_ml[i] * een_r_gl3_m[i] ) * cn;
    +        }
    +        dgl4[num] += ((dpg1_m[num] +
    +                       dtmp_c[num+elec_num*(0+4*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[0+4*(a+nucl_num*(m+l))] +
    +                      (dpg1_ml[num] +
    +                       dtmp_c[num+elec_num*(0+4*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[0+4*(a+nucl_num*m)] +
    +                      (dpg2_m[num] +
    +                       dtmp_c[num+elec_num*(1+4*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[1+4*(a+nucl_num*(m+l))] +
    +                      (dpg2_ml[num] +
    +                       dtmp_c[num+elec_num*(1+4*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[1+4*(a+nucl_num*m)] +
    +                      (dpg3_m[num] +
    +                       dtmp_c[num+elec_num*(2+4*(a+nucl_num*(m+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[2+4*(a+nucl_num*(m+l))] +
    +                      (dpg3_ml[num] +
    +                       dtmp_c[num+elec_num*(2+4*(a+nucl_num*(m+l+(cord_num+1)*(k+cord_num*nw))))]
    +                       ) * een_rescaled_delta_n_gl[2+4*(a+nucl_num*m)] ) * cn;
    +
    +      }
    +    }
    +  }
    +
    +  return QMCKL_SUCCESS;
    +}
    +
    +
    +
    +
    +
    +
    + +
    +

    5.9. \(\delta P\) matrix gradient only

    +
    +

    +To allow for more efficient treatment of nonlocal pseudopotentials, we also include a routine for only calculating the gradient (and not the Laplacian) of \(\delta J_{een}\). +For this, we calculate the gradient of \(\delta P\). +

    +
    + +
    +

    5.9.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_delta_p_g(qmckl_context context,
    +                                 double* const delta_p_g,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    5.9.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_edouble[walk_num][0:cord_num][elec_num][elec_num]inElectron-electron rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_single_edouble[walk_num][0:cord_num][elec_num]inElectron-electron single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_e_gldouble[walk_num][0:cord_num][elec_num][4][elec_num]inElectron-electron rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    een_rescaled_single_e_gldouble[walk_num][0:cord_num][elec_num][4]inElectron-electron single rescaled distances derivatives
    delta_p_gdouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][elec_num]outDelta P matrix gradient
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_jastrow_champ_delta_p_g_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     een_rescaled_n, een_rescaled_e, een_rescaled_single_n, een_rescaled_single_e, &
    +     een_rescaled_n_gl, een_rescaled_e_gl, een_rescaled_single_n_gl, een_rescaled_single_e_gl, delta_p_g) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e_gl(elec_num, 4, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e_gl(4,elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out)  :: delta_p_g(elec_num,nucl_num,4,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: delta_e_gl(elec_num,4)
    +
    +  double precision        :: een_rescaled_delta_n, een_re_n, een_re_single_n
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num
    +  double precision :: tmp, cummu
    +  integer*8        :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (num <= 0)                      info = QMCKL_INVALID_ARG_2
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +  if (cord_num == 0) then
    +     delta_p_g = 0.d0
    +     return
    +  endif
    +
    +  do nw=1, walk_num
    +     do m=1, cord_num-1
    +        do j = 1, elec_num
    +          do k = 1, 4
    +            delta_e_gl(j,k) = een_rescaled_single_e_gl(k,j,m,nw) - een_rescaled_e_gl(num, k, j, m, nw)
    +          end do
    +        end do
    +        do k = 1, 4
    +          delta_e_gl(num, k) = 0.0d0
    +        end do
    +
    +        do l=0, cord_num
    +          do k = 1, 3
    +            do a = 1, nucl_num
    +
    +              cummu = 0.0d0
    +              do i = 1, elec_num
    +                cummu = cummu + delta_e_gl(i,k) * een_rescaled_n(i,a,l,nw)
    +              end do
    +              delta_p_g(num,a,k,l,m,nw) = cummu
    +
    +
    +            end do
    +          end do
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_delta_p_g_doc
    +
    +
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_jastrow_champ_delta_p_g_hpc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     een_rescaled_n, een_rescaled_e, een_rescaled_single_n, een_rescaled_single_e, &
    +     een_rescaled_n_gl, een_rescaled_e_gl, een_rescaled_single_n_gl, een_rescaled_single_e_gl, delta_p_g) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e(elec_num, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e(elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_e_gl(elec_num, 4, elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_e_gl(4,elec_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out)  :: delta_p_g(elec_num,nucl_num,4,0:cord_num, 0:cord_num-1,  walk_num)
    +
    +  double precision        :: delta_e_gl(3,elec_num)
    +
    +  double precision        :: een_rescaled_delta_n, een_re_n, een_re_single_n
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, num
    +  double precision, allocatable :: tmp(:,:,:)
    +  integer*8        :: LDA, LDB, LDC
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (num <= 0)                      info = QMCKL_INVALID_ARG_2
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +
    +  if (cord_num == 0) then
    +     delta_p_g = 0.d0
    +     return
    +  endif
    +
    +  allocate( tmp(3,nucl_num,0:cord_num) )
    +  do nw=1, walk_num
    +     do m=1, cord_num-1
    +        delta_e_gl(1:3,1:elec_num) = een_rescaled_single_e_gl(1:3,1:elec_num,m,nw) - &
    +             een_rescaled_e_gl(num, 1:3, 1:elec_num, m, nw)
    +        delta_e_gl(1:3,num) = 0.0d0
    +
    +        call dgemm('N','N', 3, nucl_num*(cord_num+1), elec_num, 1.d0, &
    +             delta_e_gl(1,1), 3, een_rescaled_n(1,1,0,nw), elec_num, 0.d0, &
    +             tmp, 3)
    +
    +        delta_p_g(num,1:nucl_num,1,0:cord_num,m,nw) = tmp(1,1:nucl_num,0:cord_num)
    +        delta_p_g(num,1:nucl_num,2,0:cord_num,m,nw) = tmp(2,1:nucl_num,0:cord_num)
    +        delta_p_g(num,1:nucl_num,3,0:cord_num,m,nw) = tmp(3,1:nucl_num,0:cord_num)
    +     end do
    +  end do
    +  deallocate(tmp)
    +
    +end function qmckl_compute_jastrow_champ_delta_p_g_hpc
    +
    +
    + +
    +
    qmckl_exit_code
    +qmckl_compute_jastrow_champ_delta_p_g_hpc2 (const qmckl_context context,
    +                                           const int64_t num,
    +                                           const int64_t walk_num,
    +                                           const int64_t elec_num,
    +                                           const int64_t nucl_num,
    +                                           const int64_t cord_num,
    +                                           const double* een_rescaled_n,
    +                                           const double* een_rescaled_e,
    +                                           const double* een_rescaled_single_n,
    +                                           const double* een_rescaled_single_e,
    +                                           const double* een_rescaled_n_gl,
    +                                           const double* een_rescaled_e_gl,
    +                                           const double* een_rescaled_single_n_gl,
    +                                           const double* een_rescaled_single_e_gl,
    +                                           double* const delta_p_g )
    +{
    +  if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) return QMCKL_NULL_CONTEXT;
    +  if (num < 0)       return QMCKL_INVALID_ARG_2;
    +  if (walk_num <= 0) return QMCKL_INVALID_ARG_3;
    +  if (elec_num <= 0) return QMCKL_INVALID_ARG_4;
    +  if (nucl_num <= 0) return QMCKL_INVALID_ARG_5;
    +  if (cord_num <  0) return QMCKL_INVALID_ARG_6;
    +  if (een_rescaled_n == NULL) return QMCKL_INVALID_ARG_7;
    +  if (een_rescaled_e == NULL) return QMCKL_INVALID_ARG_8;
    +  if (een_rescaled_single_n == NULL) return QMCKL_INVALID_ARG_9;
    +  if (een_rescaled_single_e == NULL) return QMCKL_INVALID_ARG_10;
    +  if (een_rescaled_n_gl == NULL) return QMCKL_INVALID_ARG_11;
    +  if (een_rescaled_e_gl == NULL) return QMCKL_INVALID_ARG_12;
    +  if (een_rescaled_single_n_gl == NULL) return QMCKL_INVALID_ARG_13;
    +  if (een_rescaled_single_e_gl == NULL) return QMCKL_INVALID_ARG_14;
    +  if (delta_p_g == NULL) return QMCKL_INVALID_ARG_15;
    +
    +  if (cord_num == 0) {
    +    #pragma omp parallel for
    +    for (int64_t nw=0 ; nw<walk_num ; ++nw) {
    +      memset(&delta_p_g[elec_num*nucl_num*4*(cord_num+1)*cord_num*nw], 0,
    +             elec_num*nucl_num*4*(cord_num+1)*cord_num*sizeof(double));
    +    }
    +    return QMCKL_SUCCESS;
    +  }
    +
    +  #pragma omp parallel for
    +  for (int64_t nw=0 ; nw<walk_num ; ++nw) {
    +    double delta_e_gl[elec_num*4];
    +    for (int64_t m=1 ; m<=cord_num-1 ; ++m) {
    +      const double* een_rescaled_single_e_gl_ = &een_rescaled_single_e_gl[4*elec_num*(m+(cord_num+1)*nw)];
    +      const double* een_rescaled_e_gl_ = &een_rescaled_e_gl[num+elec_num*4*elec_num*(m+(cord_num+1)*nw)];
    +
    +      #pragma omp simd
    +      for (int64_t kj=0 ; kj<4*elec_num ; ++kj) {
    +        delta_e_gl[kj] = een_rescaled_single_e_gl_[kj] - een_rescaled_e_gl_[kj+elec_num];
    +      }
    +      #pragma omp simd
    +      for (int64_t k=0 ; k<4; ++k) {
    +        delta_e_gl[4*num+k] = 0.;
    +      }
    +
    +      for (int64_t l=0 ; l<=cord_num ; ++l) {
    +        for (int64_t k=0 ; k<3; ++k) {
    +          for (int64_t a=0 ; a<nucl_num; ++a) {
    +            double accu = 0.0;
    +            #pragma omp simd
    +            for (int64_t i=0 ; i<elec_num ; ++i) {
    +              accu += delta_e_gl[k+4*i] * een_rescaled_n[i+elec_num*(a+nucl_num*(l+(cord_num+1)*nw))];
    +            }
    +            delta_p_g[num+elec_num*(a+nucl_num*(k+4*(l+(cord_num+1)*(m+(cord_num-1+1)*nw))))] = accu;
    +          }
    +        }
    +      }
    +    }
    +  }
    +
    +  return QMCKL_SUCCESS;
    +}
    +
    +
    +
    +
    +
    + + +
    +

    5.10. Electron-electron-nucleus Jastrow gradients

    +
    +

    +Computes the gradient of the \(\delta J_{een}\). +

    +
    + +
    +

    5.10.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_een_g(qmckl_context context,
    +                                 double* const delta_een_g,
    +                                 const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_een_g (context, &
    +        delta_een_g, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_een_g(size_max)
    +   end function
    +end interface
    +
    +
    +
    +
    + +
    +

    5.10.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    cord_numint64_tinorder of polynomials
    dim_c_vectorint64_tindimension of full coefficient vector
    c_vector_fulldouble[dim_c_vector][nucl_num]infull coefficient vector
    lkpm_combined_indexint64_t[4][dim_c_vector]incombined indices
    tmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inP matrix
    dtmp_cdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][4][elec_num]inP matrix derivative
    delta_pdouble[walk_num][0:cord_num-1][0:cord_num][nucl_num][elec_num]inDelta P matrix
    delta_p_gldouble[walk_num][0:cord_num-1][0:cord_num][4][nucl_num][elec_num]inDelta P matrix derivative
    een_rescaled_ndouble[walk_num][0:cord_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    een_rescaled_single_ndouble[walk_num][0:cord_num][nucl_num]inElectron-nucleus single rescaled distances
    een_rescaled_n_gldouble[walk_num][0:cord_num][nucl_num][4][elec_num]inElectron-nucleus rescaled distances derivatives
    een_rescaled_single_n_gldouble[walk_num][0:cord_num][nucl_num][4]inElectron-nucleus single rescaled distances derivatives
    delta_een_gdouble[walk_num][4][elec_num]outDelta electron-electron-nucleus jastrow gradient
    + +
    +
    integer(qmckl_exit_code) function qmckl_compute_jastrow_champ_factor_single_een_g_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, cord_num,   &
    +     dim_c_vector, c_vector_full, lkpm_combined_index, &
    +     tmp_c, dtmp_c, delta_p, delta_p_gl, een_rescaled_n, een_rescaled_single_n, &
    +     een_rescaled_n_gl, een_rescaled_single_n_gl, delta_een_g) &
    +     result(info) bind(C)
    +  use, intrinsic :: iso_c_binding
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer(c_int64_t)    , intent(in), value  :: num_in, walk_num, elec_num, cord_num, nucl_num, dim_c_vector
    +  integer(c_int64_t)    , intent(in)  :: lkpm_combined_index(dim_c_vector,4)
    +  real(c_double)        , intent(in)  :: c_vector_full(nucl_num, dim_c_vector)
    +  real(c_double)        , intent(in)  :: tmp_c(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: dtmp_c(elec_num, 4, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: delta_p(elec_num, nucl_num,0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: delta_p_gl(elec_num, nucl_num, 4, 0:cord_num, 0:cord_num-1,  walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n(elec_num, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n(nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_n_gl(elec_num, 4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(in)  :: een_rescaled_single_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  real(c_double)        , intent(out) :: delta_een_g(elec_num, 4, walk_num)
    +
    +  integer*8 :: i, a, j, l, k, p, m, n, nw, kk, num
    +  double precision :: accu, accu2, cn
    +  integer*8                           :: LDA, LDB, LDC
    +
    +  double precision  :: een_rescaled_delta_n_gl(4, nucl_num, 0:cord_num, walk_num)
    +  double precision  :: een_rescaled_delta_n(nucl_num, 0:cord_num, walk_num)
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) info = QMCKL_INVALID_CONTEXT
    +  if (walk_num <= 0)                 info = QMCKL_INVALID_ARG_3
    +  if (elec_num <= 0)                 info = QMCKL_INVALID_ARG_4
    +  if (nucl_num <= 0)                 info = QMCKL_INVALID_ARG_5
    +  if (cord_num <  0)                 info = QMCKL_INVALID_ARG_6
    +  if (info /= QMCKL_SUCCESS)         return
    +
    +  delta_een_g = 0.0d0
    +
    +  if (cord_num == 0) return
    +
    +  een_rescaled_delta_n(:,:,:) = een_rescaled_single_n(:,:,:) - een_rescaled_n(num, :, :, :)
    +  een_rescaled_delta_n_gl(:,:,:,:) = een_rescaled_single_n_gl(:,:,:,:) - een_rescaled_n_gl(num, :,:,:,:)
    +
    +
    +  do nw =1, walk_num
    +     do n = 1, dim_c_vector
    +        l = lkpm_combined_index(n, 1)
    +        k = lkpm_combined_index(n, 2)
    +        p = lkpm_combined_index(n, 3)
    +        m = lkpm_combined_index(n, 4)
    +
    +        do kk = 1, 3
    +           do a = 1, nucl_num
    +              cn = c_vector_full(a, n)
    +              if(cn == 0.d0) cycle
    +
    +              !   delta_een_g(num,kk,nw) = delta_een_g(num,kk,nw) + ( &
    +              !        delta_p_gl(num,a,kk,m  ,k,nw) * een_rescaled_n(num,a,m+l,nw) + &
    +              !        delta_p_gl(num,a,kk,m+l,k,nw) * een_rescaled_n(num,a,m  ,nw) + &
    +              !        delta_p(num,a,m  ,k,nw) * een_rescaled_n_gl(num,kk,a,m+l,nw) + &
    +              !        delta_p(num,a,m+l,k,nw) * een_rescaled_n_gl(num,kk,a,m  ,nw) ) * cn
    +
    +              !delta_een_g(num,kk,nw) = delta_een_g(num,kk,nw) + ( &
    +              !     (dtmp_c(num,kk,a,m  ,k,nw) + delta_p_gl(num,a,kk,m  ,k,nw)) * een_rescaled_delta_n(a,m+l,nw) + &
    +              !     (dtmp_c(num,kk,a,m+l,k,nw) + delta_p_gl(num,a,kk,m+l,k,nw)) * een_rescaled_delta_n(a,m  ,nw) + &
    +              !     (tmp_c(num,a,m  ,k,nw) + delta_p(num,a,m  ,k,nw)) * een_rescaled_delta_n_gl(kk,a,m+l,nw)  + &
    +              !     (tmp_c(num,a,m+l,k,nw) + delta_p(num,a,m+l,k,nw)) * een_rescaled_delta_n_gl(kk,a,m  ,nw) )* cn
    +
    +
    +
    +              delta_een_g(num,kk,nw) = delta_een_g(num,kk,nw) + ( &
    +                   dtmp_c(num,kk,a,m  ,k,nw) * een_rescaled_delta_n(a,m+l,nw) + &
    +                   dtmp_c(num,kk,a,m+l,k,nw) * een_rescaled_delta_n(a,m  ,nw) + &
    +                   tmp_c(num,a,m  ,k,nw) * een_rescaled_delta_n_gl(kk,a,m+l,nw)  + &
    +                   tmp_c(num,a,m+l,k,nw) * een_rescaled_delta_n_gl(kk,a,m  ,nw) + &
    +                   delta_p_gl(num,a,kk,m  ,k,nw) * een_rescaled_single_n(a,m+l,nw) + &
    +                   delta_p_gl(num,a,kk,m+l,k,nw) * een_rescaled_single_n(a,m  ,nw) + &
    +                   delta_p(num,a,m  ,k,nw) * een_rescaled_single_n_gl(kk,a,m+l,nw) + & 
    +                   delta_p(num,a,m+l,k,nw) * een_rescaled_single_n_gl(kk,a,m  ,nw) )* cn
    +           end do
    +        end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_factor_single_een_g_doc
    +
    +
    +
    +
    +
    +
    + +
    +

    6. Electron-electron Jastrow

    +
    +

    +Calculates the single-electron move contribution to the \(J_{ee}\) Jastrow factor. +Similar to the 3-body case above, we need to compute the single-electron contributions to the rescaled distances. +The rescaled electron-electron distance for the 2-body term is defined as +\[ + \widetilde{r}_{ij} = \frac{1-e^{-\kappa r_{ij}}}{\kappa}. +\] +For the electron-electro Jastrow, no intermediate terms have to be calculated, as we can immidiatly calculate +\[ + \delta J_{ee} = \sum_i \sum_{j\lt i} \delta_{j,\text{num}} \left(\frac{b_1 \widetilde{r}_{ij}^{\text{new}}}{1+b_2 \widetilde{r}_{ij}^{\text{new}}} - \frac{b_1 \widetilde{r}_{ij}^{\text{old}}}{1+b_2 \widetilde{r}_{ij}^{\text{old}}} + \sum_{k=2}^{N_{\text{bord}}} b_k ({\widetilde{r}_{ij}^{\text{new}}}^k - {\widetilde{r}_{ij}^{\text{old}}}^k )\right), +\] +where num is the electron that is being moved. +The gradient and Laplacian of the rescaled distances are given by +\[ + \partial_{i,m} \widetilde{r}_{ij} = \frac{r_{i,m} - r_{j,m}}{r_{ij}} e^{-\kappa r_{ij}} \quad \text{and} \quad \partial_{i,4} \widetilde{r}_{ij} = \left(\frac{2}{r_{ij}} - \kappa \right)e^{-\kappa r_{ij}} +\] +Then, +

    +\begin{eqnarray*} + \partial_{i,m}\delta J_{ee} = & \sum_j \delta_{j,\text{num}} \left( \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{new}}_{ij}}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} - \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{old}}_{ij}}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{new}}_{ij} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{old}}_{ij} \right) \right)\\ + \partial_{i,4}\delta J_{ee} = & \sum_j \delta_{j,\text{num}} \left( \frac{b_1}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{new}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{new}}_{ij} \cdot \nabla \widetilde{r}^{\text{new}}_{ij}}{1+b_2 \widetilde{r}^{\text{new}}_{ij}} \right) - \frac{b_1}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{old}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{old}}_{ij} \cdot \nabla \widetilde{r}^{\text{old}}_{ij}}{1+b_2 \widetilde{r}^{\text{old}}_{ij}} \right) \right.\\ + & \left.+ \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{new}} + (k-1)(\nabla\widetilde{r}_{ij}^{\text{new}} \cdot \nabla \widetilde{r}_{ij}^{\text{new}}) {\widetilde{r}_{ij}^{\text{new}}}^{k-2} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{old}} - (k-1)(\nabla\widetilde{r}_{ij}^{\text{old}} \cdot \nabla \widetilde{r}_{ij}^{\text{old}}) {\widetilde{r}_{ij}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +

    +In the special case that \(i = \text{num}\), the gradient and Laplacian change to +

    +\begin{eqnarray*} + \partial_{\text{num},m}\delta J_{ee} = & -\sum_i \sum_j \delta_{j,\text{num}} \left(\frac{b_1 \partial_{i,m}\widetilde{r}^{\text{new}}_{ij}}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} - \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{old}}_{ij}}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{new}}_{ij} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{old}}_{ij} \right) \right) \\ + \partial_{\text{num},4}\delta J_{ee} = & -\sum_i \sum_j \delta_{j,\text{num}} \left( \frac{b_1}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{new}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{new}}_{ij} \cdot \nabla \widetilde{r}^{\text{new}}_{ij}}{1+b_2 \widetilde{r}^{\text{new}}_{ij}} \right) - \frac{b_1}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{old}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{old}}_{ij} \cdot \nabla \widetilde{r}^{\text{old}}_{ij}}{1+b_2 \widetilde{r}^{\text{old}}_{ij}} \right)\right. \\ + & \left. + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{new}} + (k-1)(\nabla\widetilde{r}_{ij}^{\text{new}} \cdot \nabla \widetilde{r}_{ij}^{\text{new}}) {\widetilde{r}_{ij}^{\text{new}}}^{k-2} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{old}} - (k-1)(\nabla\widetilde{r}_{ij}^{\text{old}} \cdot \nabla \widetilde{r}_{ij}^{\text{old}}) {\widetilde{r}_{ij}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +
    +
    +

    6.1. Electron-electron rescaled distance

    +
    +

    +Calculates the rescaled electron-electron distances +\[ + \widetilde{r}_{ij} = \frac{1-e^{-\kappa r_{ij}}}{\kappa}. +\] +

    +
    + +
    +

    6.1.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_ee_rescaled_single(qmckl_context context,
    +                                 double* const distance_rescaled,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    6.1.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    elec_numint64_tinNumber of electrons
    rescale_factor_eedoubleinFactor to rescale ee distances
    walk_numint64_tinNumber of walkers
    single_ee_distancedouble[walk_num][elec_num]inSingle electron-electron distances
    ee_rescaled_singledouble[walk_num][elec_num]outElectron-electron rescaled distances
    + +
    +
    function qmckl_compute_ee_rescaled_single_doc(context, &
    +     elec_num, rescale_factor_ee, walk_num, &
    +     single_ee_distance, ee_rescaled_single) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer(qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  real    (c_double ) , intent(in)  , value :: rescale_factor_ee
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  real    (c_double ) , intent(in)          :: single_ee_distance(elec_num,walk_num)
    +  real    (c_double ) , intent(out)         :: ee_rescaled_single(elec_num,walk_num)
    +  integer(qmckl_exit_code)                  :: info
    +
    +  integer*8 :: k, i
    +  real (c_double) :: inverse_rescale_factor_ee
    +
    +  inverse_rescale_factor_ee = 1.0d0 / rescale_factor_ee
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  do k=1,walk_num
    +      do i=1,elec_num
    +     ee_rescaled_single(i,k) = (1.0d0 - dexp(-rescale_factor_ee * single_ee_distance(i,k))) * inverse_rescale_factor_ee
    +     enddo
    +  end do
    +
    +end function qmckl_compute_ee_rescaled_single_doc
    +
    +
    +
    +
    +
    + +
    +

    6.2. Electron-electron Jastrow value

    +
    +

    +Calculate the single-electron move contribution to the \(J_{ee}\) Jastrow factor. +\[ + \delta J_{ee} = \sum_i \sum_{j\lt i} \delta_{j,\text{num}} \left(\frac{b_1 \widetilde{r}_{ij}^{\text{new}}}{1+b_2 \widetilde{r}_{ij}^{\text{new}}} - \frac{b_1 \widetilde{r}_{ij}^{\text{old}}}{1+b_2 \widetilde{r}_{ij}^{\text{old}}} + \sum_{k=2}^{N_{\text{bord}}} b_k ({\widetilde{r}_{ij}^{\text{new}}}^k - {\widetilde{r}_{ij}^{\text{old}}}^k )\right), +\] +

    +
    + +
    +

    6.2.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_ee(qmckl_context context,
    +                            double* const delta_ee,
    +                            const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_ee (context, &
    +        delta_ee, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_ee(size_max)
    +   end function qmckl_get_jastrow_champ_single_ee
    +end interface
    +
    +
    +
    +
    + +
    +

    6.2.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single point
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    up_numint64_tinNumber of alpha electrons
    bord_numint64_tinNumber of coefficients
    b_vectordouble[bord_num+1]inList of coefficients
    ee_distance_rescaleddouble[walk_num][elec_num][elec_num]inElectron-electron rescaled distances
    ee_rescaled_singledouble[walk_num][elec_num]inElectron-electron rescaled single distances
    delta_eedouble[walk_num]outSingle electron-electron Jastrow
    + +
    +
    function qmckl_compute_jastrow_champ_single_ee_doc(context, &
    +     num_in, walk_num, elec_num, up_num, bord_num, b_vector, &
    +     ee_distance_rescaled, ee_rescaled_single, spin_independent, delta_ee) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t)    , intent(in), value :: num_in
    +  integer (c_int64_t)    , intent(in), value :: walk_num
    +  integer (c_int64_t)    , intent(in), value :: elec_num
    +  integer (c_int64_t)    , intent(in), value :: up_num
    +  integer (c_int64_t)    , intent(in), value :: bord_num
    +  real    (c_double )    , intent(in)        :: b_vector(bord_num+1)
    +  real    (c_double )    , intent(in)        :: ee_distance_rescaled(elec_num,elec_num,walk_num)
    +  real    (c_double )    , intent(in)        :: ee_rescaled_single(elec_num,walk_num)
    +  integer (c_int32_t)    , intent(in), value :: spin_independent
    +  real    (c_double )    , intent(out)       :: delta_ee(walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, j, k, nw, num
    +  double precision   :: x, xk, y, yk
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (bord_num < 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +
    +     delta_ee(nw) = 0.0d0
    +     do i=1,elec_num
    +         !print *,i, ee_rescaled_single(i,nw)
    +         !print *, i, ee_distance_rescaled(i,num,nw)
    +         !print *, '   '
    +        if (i.ne.num) then
    +           x = ee_distance_rescaled(i,num,nw)
    +           y = ee_rescaled_single(i,nw)
    +           if (spin_independent == 1) then
    +              delta_ee(nw) = delta_ee(nw) - (b_vector(1) * x / (1.d0 + b_vector(2) * x)) &
    +                   + (b_vector(1) * y / (1.d0 + b_vector(2) * y))
    +           else
    +              if ((i <= up_num .and. num <= up_num ) .or. (i >  up_num .and. num >  up_num)) then
    +                 delta_ee(nw) = delta_ee(nw) - (0.5d0 * b_vector(1) * x / (1.d0 + b_vector(2) * x)) &
    +                      + (0.5d0 * b_vector(1) * y / (1.d0 + b_vector(2) * y))
    +              else
    +                 delta_ee(nw) = delta_ee(nw) - (b_vector(1) * x / (1.d0 + b_vector(2) * x)) &
    +                      + (b_vector(1) * y / (1.d0 + b_vector(2) * y))
    +              endif
    +           endif
    +
    +           xk = x
    +           yk = y
    +           do k=2,bord_num
    +              xk = xk * x
    +              yk = yk * y
    +              delta_ee(nw) = delta_ee(nw) - (b_vector(k+1) * xk) + (b_vector(k+1) * yk)
    +           end do
    +        endif
    +     end do
    +
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_single_ee_doc
    +
    +
    +
    +
    +
    + +
    +

    6.3. Electron-electron rescaled distances derivatives

    +
    +

    +Calculate the derivative of the rescaled electron-electron distances. +\[ + \partial_{i,m} \widetilde{r}_{ij} = \frac{r_{i,m} - r_{j,m}}{r_{ij}} e^{-\kappa r_{ij}} \quad \text{and} \quad \partial_{i,4} \widetilde{r}_{ij} = \left(\frac{2}{r_{ij}} - \kappa \right)e^{-\kappa r_{ij}} +\] +

    +
    + +
    +

    6.3.1. Get

    +
    +
    +
    qmckl_exit_code qmckl_get_ee_rescaled_single_gl(qmckl_context context,
    +                                                double* const distance_rescaled_gl,
    +                                                const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    6.3.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    elec_numint64_tinNumber of electrons
    rescale_factor_eedoubleinFactor to rescale ee distances
    walk_numint64_tinNumber of walkers
    single_ee_distancedouble[elec_num][walk_num]inSingle electron-electron distances
    elec_coorddouble[3][walk_num][elec_num]inElectron coordinates
    coorddouble[walk_num][3]inSingle electron coordinates
    ee_rescaled_single_gldouble[walk_num][elec_num][4]outElectron-electron rescaled single distance derivatives
    + +
    +
    function qmckl_compute_ee_rescaled_single_gl_doc(context, num_in,  &
    +     elec_num, rescale_factor_ee, walk_num, single_ee_distance, elec_coord, coord, ee_rescaled_single_gl) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer(qmckl_context), intent(in), value :: context
    +   integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  real    (c_double ) , intent(in)  , value :: rescale_factor_ee
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  real    (c_double ) , intent(in)          :: single_ee_distance(elec_num,walk_num)
    +  real    (c_double ) , intent(in)          :: elec_coord(elec_num,walk_num,3)
    +  real    (c_double ) , intent(in)          :: coord(3,walk_num)
    +  real    (c_double ) , intent(out)         :: ee_rescaled_single_gl(4,elec_num,walk_num)
    +  integer(qmckl_exit_code)                  :: info
    +
    +  integer*8 :: nw, i, ii, num
    +  double precision :: rij_inv, elel_dist_gl(4, elec_num), kappa_l
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +
    +  ee_rescaled_single_gl = 0.0d0
    +  do nw = 1, walk_num
    +
    +     ! prepare the actual een table
    +     do i = 1, elec_num
    +        rij_inv = 1.0d0 / single_ee_distance(i, nw)
    +        do ii = 1, 3
    +          elel_dist_gl(ii, i) = (elec_coord(i,nw, ii) - coord(ii,nw)) * rij_inv
    +        end do
    +        elel_dist_gl(4, i) = 2.0d0 * rij_inv
    +     end do
    +
    +      do i = 1, elec_num
    +        kappa_l = -1 * rescale_factor_ee
    +        ee_rescaled_single_gl(1, i, nw) = elel_dist_gl(1, i)
    +        ee_rescaled_single_gl(2, i, nw) = elel_dist_gl(2, i)
    +        ee_rescaled_single_gl(3, i, nw) = elel_dist_gl(3, i)
    +        ee_rescaled_single_gl(4, i, nw) = elel_dist_gl(4, i)
    +
    +        ee_rescaled_single_gl(4, i, nw) = ee_rescaled_single_gl(4, i, nw) + kappa_l
    +
    +        ee_rescaled_single_gl(1, i, nw) = ee_rescaled_single_gl(1, i, nw)  * dexp(kappa_l * single_ee_distance(i,nw))
    +        ee_rescaled_single_gl(2, i, nw) = ee_rescaled_single_gl(2, i, nw)  * dexp(kappa_l * single_ee_distance(i,nw))
    +        ee_rescaled_single_gl(3, i, nw) = ee_rescaled_single_gl(3, i, nw)  * dexp(kappa_l * single_ee_distance(i,nw))
    +        ee_rescaled_single_gl(4, i, nw) = ee_rescaled_single_gl(4, i, nw)  * dexp(kappa_l * single_ee_distance(i,nw))
    +     end do
    +
    +     ee_rescaled_single_gl(1, num, nw) = 0.0d0
    +     ee_rescaled_single_gl(2, num, nw) = 0.0d0
    +     ee_rescaled_single_gl(3, num, nw) = 0.0d0
    +     ee_rescaled_single_gl(4, num, nw) = 0.0d0
    +  end do
    +
    +
    +end function qmckl_compute_ee_rescaled_single_gl_doc
    +
    +
    +
    +
    +
    + +
    +

    6.4. Electron-electron Jastrow gradients and Laplacian

    +
    +

    +Calculates the gradient and Laplacian of the electron-electron Jastrow factor. +

    +\begin{eqnarray*} + \partial_{i,m}\delta J_{ee} = & \sum_j \delta_{j,\text{num}} \left( \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{new}}_{ij}}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} - \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{old}}_{ij}}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{new}}_{ij} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{old}}_{ij} \right) \right)\\ + \partial_{i,4}\delta J_{ee} = & \sum_j \delta_{j,\text{num}} \left( \frac{b_1}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{new}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{new}}_{ij} \cdot \nabla \widetilde{r}^{\text{new}}_{ij}}{1+b_2 \widetilde{r}^{\text{new}}_{ij}} \right) - \frac{b_1}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{old}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{old}}_{ij} \cdot \nabla \widetilde{r}^{\text{old}}_{ij}}{1+b_2 \widetilde{r}^{\text{old}}_{ij}} \right) \right.\\ + & \left.+ \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{new}} + (k-1)(\nabla\widetilde{r}_{ij}^{\text{new}} \cdot \nabla \widetilde{r}_{ij}^{\text{new}}) {\widetilde{r}_{ij}^{\text{new}}}^{k-2} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{old}} - (k-1)(\nabla\widetilde{r}_{ij}^{\text{old}} \cdot \nabla \widetilde{r}_{ij}^{\text{old}}) {\widetilde{r}_{ij}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +

    +In the special case that \(i = \text{num}\), the gradient and Laplacian change to +

    +\begin{eqnarray*} + \partial_{\text{num},m}\delta J_{ee} = & -\sum_i \sum_j \delta_{j,\text{num}} \left(\frac{b_1 \partial_{i,m}\widetilde{r}^{\text{new}}_{ij}}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} - \frac{b_1 \partial_{i,m}\widetilde{r}^{\text{old}}_{ij}}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{new}}_{ij} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{r}^{\text{old}}_{ij} \right) \right) \\ + \partial_{\text{num},4}\delta J_{ee} = & -\sum_i \sum_j \delta_{j,\text{num}} \left( \frac{b_1}{(1+b_2 \widetilde{r}^{\text{new}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{new}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{new}}_{ij} \cdot \nabla \widetilde{r}^{\text{new}}_{ij}}{1+b_2 \widetilde{r}^{\text{new}}_{ij}} \right) - \frac{b_1}{(1+b_2 \widetilde{r}^{\text{old}}_{ij})^2} \left(\partial_{i,4}\widetilde{r}^{\text{old}}_{ij} - 2 b_2 \frac{\nabla\widetilde{r}^{\text{old}}_{ij} \cdot \nabla \widetilde{r}^{\text{old}}_{ij}}{1+b_2 \widetilde{r}^{\text{old}}_{ij}} \right)\right. \\ + & \left. + \sum_{k=2}^{N_{\text{bord}}} b_k k \left({\widetilde{r}_{ij}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{new}} + (k-1)(\nabla\widetilde{r}_{ij}^{\text{new}} \cdot \nabla \widetilde{r}_{ij}^{\text{new}}) {\widetilde{r}_{ij}^{\text{new}}}^{k-2} - {\widetilde{r}_{ij}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{r}_{ij}^{\text{old}} - (k-1)(\nabla\widetilde{r}_{ij}^{\text{old}} \cdot \nabla \widetilde{r}_{ij}^{\text{old}}) {\widetilde{r}_{ij}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +
    + +
    +

    6.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_ee_gl(qmckl_context context,
    +                                    double* const delta_ee_gl,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_ee_gl (context, &
    +        delta_ee_gl, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_ee_gl(size_max)
    +   end function qmckl_get_jastrow_champ_single_ee_gl
    +end interface
    +
    +
    +
    +
    + +
    +

    6.4.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    up_numint64_tinNumber of alpha electrons
    bord_numint64_tinNumber of coefficients
    b_vectordouble[bord_num+1]inList of coefficients
    ee_distance_rescaleddouble[walk_num][elec_num][elec_num]inElectron-electron rescaled distances
    ee_distance_rescaled_gldouble[walk_num][4][elec_num][elec_num]inElectron-electron rescaled distances derivatives
    ee_rescaled_singledouble[walk_num][elec_num]inElectron-electron rescaled single distances
    ee_rescaled_single_gldouble[walk_num][4][elec_num]inElectron-electron rescaled single distances derivatives
    spin_independentint32_tinIf 1, same parameters for parallel and antiparallel spins
    delta_ee_gldouble[walk_num][elec_num][4]outSingle electron-electron jastrow gradients and Laplacian
    + +
    +
    function qmckl_compute_jastrow_champ_single_ee_gl_doc( &
    +     context, num_in, walk_num, elec_num, up_num, bord_num, &
    +     b_vector, ee_distance_rescaled, ee_distance_rescaled_gl,  &
    +     ee_rescaled_single, ee_rescaled_single_gl,  &
    +     spin_independent, delta_ee_gl) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: up_num
    +  integer (c_int64_t) , intent(in)  , value :: bord_num
    +  real    (c_double ) , intent(in)          :: b_vector(bord_num+1)
    +  real    (c_double ) , intent(in)          :: ee_distance_rescaled(elec_num,elec_num,walk_num)
    +  real    (c_double ) , intent(in)          :: ee_distance_rescaled_gl(4,elec_num,elec_num,walk_num)
    +  real    (c_double ) , intent(in)          :: ee_rescaled_single(elec_num,walk_num)
    +  real    (c_double ) , intent(in)          :: ee_rescaled_single_gl(4,elec_num,walk_num)
    +  integer (c_int32_t) , intent(in)  , value :: spin_independent
    +  real    (c_double ) , intent(out)         :: delta_ee_gl(4,elec_num,walk_num)
    +  integer(qmckl_exit_code)                  :: info
    +
    +  integer*8 :: i, j, k, nw, ii, num
    +  double precision   :: x, x1, kf, x_old, x1_old
    +  double precision   :: denom, invdenom, invdenom2, f
    +  double precision   :: denom_old, invdenom_old, invdenom2_old, f_old
    +  double precision   :: grad_c2, grad_c2_old
    +  double precision   :: dx(4), dx_old(4)
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (bord_num < 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +  if ((spin_independent < 0).or.(spin_independent > 1)) then
    +     info = QMCKL_INVALID_ARG_8
    +     return
    +  endif
    +
    +  do nw =1, walk_num
    +     delta_ee_gl(:,:,nw) = 0.0d0
    +        do i = 1, elec_num
    +           if (i == num) cycle
    +
    +           x = ee_rescaled_single(i,nw)
    +           x_old = ee_distance_rescaled(i,num,nw)
    +
    +           denom         = 1.0d0 + b_vector(2) * x
    +           invdenom      = 1.0d0 / denom
    +           invdenom2     = invdenom * invdenom
    +
    +           denom_old         = 1.0d0 + b_vector(2) * x_old
    +           invdenom_old      = 1.0d0 / denom_old
    +           invdenom2_old     = invdenom_old * invdenom_old
    +
    +           dx(1) = ee_rescaled_single_gl(1, i, nw)
    +           dx(2) = ee_rescaled_single_gl(2, i, nw)
    +           dx(3) = ee_rescaled_single_gl(3, i, nw)
    +           dx(4) = ee_rescaled_single_gl(4, i, nw)
    +
    +           dx_old(1) = ee_distance_rescaled_gl(1, i, num, nw)
    +           dx_old(2) = ee_distance_rescaled_gl(2, i, num, nw)
    +           dx_old(3) = ee_distance_rescaled_gl(3, i, num, nw)
    +           dx_old(4) = ee_distance_rescaled_gl(4, i, num, nw)
    +
    +           grad_c2 = dx(1)*dx(1) + dx(2)*dx(2) + dx(3)*dx(3)
    +           grad_c2_old = dx_old(1)*dx_old(1) + dx_old(2)*dx_old(2) + dx_old(3)*dx_old(3)
    +
    +           if (spin_independent == 1) then
    +              f = b_vector(1) * invdenom2
    +              f_old = b_vector(1) * invdenom2_old
    +           else
    +              if((i <= up_num .and. num <= up_num ) .or. (i >  up_num .and. num >  up_num)) then
    +                 f = 0.5d0 * b_vector(1) * invdenom2
    +                 f_old = 0.5d0 * b_vector(1) * invdenom2_old
    +              else
    +                 f = b_vector(1) * invdenom2
    +                 f_old = b_vector(1) * invdenom2_old
    +              end if
    +           end if
    +
    +           delta_ee_gl(1,i,nw) = delta_ee_gl(1,i,nw) + f * dx(1) - f_old * dx_old(1)
    +           delta_ee_gl(2,i,nw) = delta_ee_gl(2,i,nw) + f * dx(2) - f_old * dx_old(2)
    +           delta_ee_gl(3,i,nw) = delta_ee_gl(3,i,nw) + f * dx(3) - f_old * dx_old(3)
    +           delta_ee_gl(4,i,nw) = delta_ee_gl(4,i,nw) &
    +                + f * (dx(4) - 2.d0 * b_vector(2) * grad_c2 * invdenom) &
    +                - f_old * (dx_old(4) - 2.d0 * b_vector(2) * grad_c2_old * invdenom_old)
    +
    +           delta_ee_gl(1,num,nw) = delta_ee_gl(1,num,nw) - f * dx(1) + f_old * dx_old(1)
    +           delta_ee_gl(2,num,nw) = delta_ee_gl(2,num,nw) - f * dx(2) + f_old * dx_old(2)
    +           delta_ee_gl(3,num,nw) = delta_ee_gl(3,num,nw) - f * dx(3) + f_old * dx_old(3)
    +           delta_ee_gl(4,num,nw) = delta_ee_gl(4,num,nw) &
    +                + f * (dx(4) - 2.d0 * b_vector(2) * grad_c2 * invdenom) &
    +                - f_old * (dx_old(4) - 2.d0 * b_vector(2) * grad_c2_old * invdenom_old)
    +
    +
    +           kf = 2.d0
    +           x1 = x
    +           x1_old = x_old
    +           x = 1.d0
    +           x_old = 1.d0
    +           do k=2, bord_num
    +              f = b_vector(k+1) * kf * x
    +              f_old = b_vector(k+1) * kf * x_old
    +              delta_ee_gl(1,i,nw) = delta_ee_gl(1,i,nw) + f * x1 * dx(1) - f_old * x1_old * dx_old(1)
    +              delta_ee_gl(2,i,nw) = delta_ee_gl(2,i,nw) + f * x1 * dx(2) - f_old * x1_old * dx_old(2)
    +              delta_ee_gl(3,i,nw) = delta_ee_gl(3,i,nw) + f * x1 * dx(3) - f_old * x1_old * dx_old(3)
    +              delta_ee_gl(4,i,nw) = delta_ee_gl(4,i,nw) &
    +                   + f * (x1 * dx(4) + (kf-1.d0) * grad_c2) &
    +                   - f_old * (x1_old * dx_old(4) + (kf-1.d0) * grad_c2_old)
    +
    +              delta_ee_gl(1,num,nw) = delta_ee_gl(1,num,nw) - f * x1 * dx(1) + f_old * x1_old * dx_old(1)
    +              delta_ee_gl(2,num,nw) = delta_ee_gl(2,num,nw) - f * x1 * dx(2) + f_old * x1_old * dx_old(2)
    +              delta_ee_gl(3,num,nw) = delta_ee_gl(3,num,nw) - f * x1 * dx(3) + f_old * x1_old * dx_old(3)
    +              delta_ee_gl(4,num,nw) = delta_ee_gl(4,num,nw) &
    +                   + f * (x1 * dx(4) + (kf-1.d0) * grad_c2) &
    +                   - f_old * (x1_old * dx_old(4) + (kf-1.d0) * grad_c2_old)
    +              x = x*x1
    +              x_old = x_old*x1_old
    +              kf = kf + 1.d0
    +           end do
    +
    +
    +        end do
    +
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_single_ee_gl_doc
    +
    +
    +
    +
    +
    +
    + +
    +

    7. Electron-nucleus Jastrow

    +
    +

    +Here we calculate the single-electron move contribution to the \(J_{en}\) Jastrow factor. +First, we need to compute the single-electron contributions to the rescaled distances. +The rescaled electron-electron distance for the 2-body term is defined as +\[ + \widetilde{R}_{i\alpha} = \frac{1-e^{-\kappa R_{i\alpha}}}{\kappa}. +\] +For the electron-nucleus Jastrow, no intermediate terms have to be calculated, as we can immidiatly calculate +\[ + \delta J_{en} = \sum_i \delta_{i,\text{num}} \left( \frac{a_1 \widetilde{R}_{i\alpha}^{\text{new}}}{1+a_2 \widetilde{R}_{i\alpha}^{\text{new}}} - \frac{a_1 \widetilde{R}_{i\alpha}^{\text{old}}}{1+a_2 \widetilde{R}_{i\alpha}^{\text{old}}} + \sum_{k=2}^{N_\text{aord}} a_k\left({\widetilde{R}_{i\alpha}^{\text{new}}}^k - {\widetilde{R}_{i\alpha}^{\text{old}}}^k \right)\right) +\] +where num is the electron that is being moved. +The gradient and Laplacian of the rescaled distances are given by +\[ + \partial_{i,m} \widetilde{R}_{i\alpha} = \frac{r_{i,m} - R_{\alpha,m}}{R_{i\alpha}} e^{-\kappa R_{i\alpha}} \quad \text{and} \quad \partial_{i,4} \widetilde{R}_{i\alpha} = \left(\frac{2}{R_{i\alpha}} - \kappa \right)e^{-\kappa R_{i\alpha}} +\] +Then, +

    +\begin{eqnarray*} + \partial_{i,m}\delta J_{en} = & \sum_\alpha \delta_{i,\text{num}} \left( \frac{a_1 \partial_{i,m}\widetilde{R}^{\text{new}}_{i\alpha}}{(1+a_2 \widetilde{R}^{\text{new}}_{i\alpha})^2} - \frac{a_1 \partial_{i,m}\widetilde{R}^{\text{old}}_{i\alpha}}{(1+a_2 \widetilde{R}^{\text{old}}_{i\alpha})^2} + \sum_{k=2}^{N_{\text{aord}}} a_k k \left({\widetilde{R}_{i\alpha}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{R}^{\text{new}}_{i\alpha} - {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{R}^{\text{old}}_{i\alpha} \right) \right)\\ + \partial_{i,4}\delta J_{en} = & \sum_\alpha \delta_{i,\text{num}} \left( \frac{a_1}{(1+a_2 \widetilde{R}^{\text{new}}_{i\alpha})^2} \left(\partial_{i,4}\widetilde{R}^{\text{new}}_{i\alpha} - 2 a_2 \frac{\nabla\widetilde{R}^{\text{new}}_{i\alpha} \cdot \nabla \widetilde{R}^{\text{new}}_{i\alpha}}{1+a_2 \widetilde{R}^{\text{new}}_{i\alpha}} \right) - \frac{a_1}{(1+a_2 \widetilde{R}^{\text{old}}_{i\alpha})^2} \left(\partial_{i,4}\widetilde{R}^{\text{old}}_{i\alpha} - 2 a_2 \frac{\nabla\widetilde{R}^{\text{old}}_{i\alpha} \cdot \nabla \widetilde{R}^{\text{old}}_{i\alpha}}{1+b_2 \widetilde{R}^{\text{old}}_{i\alpha}} \right) \right.\\ + & \left.+ \sum_{k=2}^{N_{\text{aord}}} a_k k \left({\widetilde{R}_{i\alpha}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{R}_{i\alpha}^{\text{new}} + (k-1)(\nabla\widetilde{R}_{i\alpha}^{\text{new}} \cdot \nabla \widetilde{R}_{i\alpha}^{\text{new}}) {\widetilde{R}_{i\alpha}^{\text{new}}}^{k-2} - {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{R}_{i\alpha}^{\text{old}} - (k-1)(\nabla\widetilde{R}_{i\alpha}^{\text{old}} \cdot \nabla \widetilde{R}_{i\alpha}^{\text{old}}) {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +
    + + +
    +

    7.1. Electron-nucleus rescaled distance

    +
    +

    +Calculate the updated rescaled electron-nucleus distances +\[ + \widetilde{R}_{i\alpha} = \frac{1-e^{-\kappa R_{i\alpha}}}{\kappa}. +\] +

    +
    + +
    +

    7.1.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_en_rescaled_single(qmckl_context context,
    +                                 double* const distance_rescaled,
    +                                 const int64_t size_max);
    +
    +
    +
    +
    + +
    +

    7.1.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of types of nuclei
    type_nucl_vectorint64_t[nucl_num]inNumber of types of nuclei
    rescale_factor_endouble[type_nucl_num]inThe factor for rescaled distances
    walk_numint64_tinNumber of walkers
    single_en_distancedouble[walk_num][nucl_num]inSingle electron-nucleus distances
    en_rescaled_singledouble[walk_num][nucl_num]outElectron-nucleus rescaled distances
    + +
    +
    function qmckl_compute_en_rescaled_single_doc(context, &
    +     nucl_num, type_nucl_num, type_nucl_vector, rescale_factor_en, &
    +     walk_num, single_en_distance, en_rescaled_single) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value  :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value  :: type_nucl_num
    +  integer (c_int64_t) , intent(in)           :: type_nucl_vector(nucl_num)
    +  real    (c_double ) , intent(in)           :: rescale_factor_en(type_nucl_num)
    +  integer (c_int64_t) , intent(in)  , value  :: walk_num
    +  real    (c_double ) , intent(in)           :: single_en_distance(nucl_num,walk_num)
    +  real    (c_double ) , intent(out)          :: en_rescaled_single(nucl_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, k
    +  double precision      :: coord(3)
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  do i=1, nucl_num
    +     do k=1,walk_num
    +        en_rescaled_single(i,k) = (1.0d0 - dexp(-rescale_factor_en(type_nucl_vector(i)+1) * &
    +             single_en_distance(i,k))) / rescale_factor_en(type_nucl_vector(i)+1)
    +     end do
    +  end do
    +
    +end function qmckl_compute_en_rescaled_single_doc
    +
    +
    +
    +
    +
    + + + +
    +

    7.2. Single electron-nucleus Jastrow value

    +
    +

    +Calculates \(\delta J_{en}\) +\[ + \delta J_{en} = \sum_i \delta_{i,\text{num}} \left( \frac{a_1 \widetilde{R}_{i\alpha}^{\text{new}}}{1+a_2 \widetilde{R}_{i\alpha}^{\text{new}}} - \frac{a_1 \widetilde{R}_{i\alpha}^{\text{old}}}{1+a_2 \widetilde{R}_{i\alpha}^{\text{old}}} + \sum_{k=2}^{N_\text{aord}} a_k\left({\widetilde{R}_{i\alpha}^{\text{new}}}^k - {\widetilde{R}_{i\alpha}^{\text{old}}}^k \right)\right) +\] +

    +
    + +
    +

    7.2.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_en(qmckl_context context,
    +                            double* const delta_en,
    +                            const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_en (context, &
    +        delta_en, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_en(size_max)
    +   end function qmckl_get_jastrow_champ_single_en
    +end interface
    +
    +
    +
    +
    + +
    +

    7.2.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single point
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    ~enrescaledsingle ~double[walk_num][nucl_num]inElectron-nucleus rescaled single distances
    delta_endouble[walk_num]outSingle electron-nucleus jastrow
    + +
    +
    function qmckl_compute_jastrow_champ_single_en_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, &
    +     en_distance_rescaled, en_rescaled_single, delta_en) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_rescaled_single(nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: delta_en(walk_num)
    +  integer(qmckl_exit_code)                  :: info
    +
    +  integer*8 :: i, a, p, nw, num
    +  double precision   :: x, power_ser, y
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (type_nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_7
    +     return
    +  endif
    +
    +
    +  do nw =1, walk_num
    +     delta_en(nw) = 0.0d0
    +     do a = 1, nucl_num
    +          x = en_distance_rescaled(num, a, nw)
    +          y = en_rescaled_single(a, nw)
    +
    +          delta_en(nw) = delta_en(nw) - a_vector(1, type_nucl_vector(a)+1) * x / (1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x)
    +          delta_en(nw) = delta_en(nw) + a_vector(1, type_nucl_vector(a)+1) * y / (1.0d0 + a_vector(2, type_nucl_vector(a)+1) * y)
    +
    +          do p = 2, aord_num
    +            x = x * en_distance_rescaled(num, a, nw)
    +            y = y * en_rescaled_single(a, nw)
    +            delta_en(nw) = delta_en(nw) - a_vector(p + 1, type_nucl_vector(a)+1) * x + a_vector(p + 1, type_nucl_vector(a)+1) * y
    +          end do
    +
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_single_en_doc
    +
    +
    +
    +
    +
    + + +
    +

    7.3. Electron-nucleus rescaled distances derivatives

    +
    +

    +Calculate the gradients and Laplacians of the rescaled electron-nucleus distances +\[ + \partial_{i,m} \widetilde{R}_{i\alpha} = \frac{r_{i,m} - R_{\alpha,m}}{R_{i\alpha}} e^{-\kappa R_{i\alpha}} \quad \text{and} \quad \partial_{i,4} \widetilde{R}_{i\alpha} = \left(\frac{2}{R_{i\alpha}} - \kappa \right)e^{-\kappa R_{i\alpha}} +\] +

    +
    + +
    +

    7.3.1. Get

    +
    +
    +
    qmckl_exit_code qmckl_get_en_rescaled_single_gl(qmckl_context context,
    +                                                double* distance_rescaled_gl,
    +                                                const size_t size_max);
    +
    +
    +
    +
    + +
    +

    7.3.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of nucleus types
    type_nucl_vectorint64_t[nucl_num]inArray of nucleus types
    rescale_factor_endouble[nucl_num]inThe factors for rescaled distances
    walk_numint64_tinNumber of walkers
    single_en_distancedouble[walk_num][nucl_num]inSingle electorn distances
    coorddouble[walk_num][3]inSingle electron coordinates
    nucl_coorddouble[3][nucl_num]inNucleus coordinates
    en_rescaled_single_gldouble[walk_num][nucl_num][4]outElectron-nucleus rescaled single distance derivatives
    + +
    +
    integer function qmckl_compute_en_rescaled_single_gl_doc_f(context, nucl_num, &
    +     type_nucl_num, type_nucl_vector, rescale_factor_en, walk_num, &
    +     single_en_distance, coord, nucl_coord, en_rescaled_single_gl) &
    +     result(info)
    +  use qmckl
    +  implicit none
    +  integer(qmckl_context), intent(in)  :: context
    +  integer*8             , intent(in)  :: nucl_num
    +  integer*8             , intent(in)  :: type_nucl_num
    +  integer*8             , intent(in)  :: type_nucl_vector(nucl_num)
    +  double precision      , intent(in)  :: rescale_factor_en(nucl_num)
    +  integer*8             , intent(in)  :: walk_num
    +  double precision      , intent(in)  :: single_en_distance(nucl_num, walk_num)
    +  double precision      , intent(in)  :: coord(3,walk_num)
    +  double precision      , intent(in)  :: nucl_coord(nucl_num,3)
    +  double precision      , intent(out) :: en_rescaled_single_gl(4,nucl_num,walk_num)
    +
    +  integer*8 :: nw, a, ii
    +  double precision :: ria_inv, elnuc_dist_gl(4, nucl_num), kappa_l
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_2
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +
    +  en_rescaled_single_gl = 0.0d0
    +  do nw = 1, walk_num
    +
    +     ! prepare the actual een table
    +     do a = 1, nucl_num
    +        ria_inv = 1.0d0 / single_en_distance(a, nw)
    +        do ii = 1, 3
    +          elnuc_dist_gl(ii, a) = (coord(ii,nw) - nucl_coord(a, ii)) * ria_inv
    +        end do
    +        elnuc_dist_gl(4, a) = 2.0d0 * ria_inv
    +     end do
    +
    +      do a = 1, nucl_num
    +        kappa_l = -1 * rescale_factor_en(type_nucl_vector(a)+1)
    +        en_rescaled_single_gl(1, a, nw) = elnuc_dist_gl(1, a)
    +        en_rescaled_single_gl(2, a, nw) = elnuc_dist_gl(2, a)
    +        en_rescaled_single_gl(3, a, nw) = elnuc_dist_gl(3, a)
    +        en_rescaled_single_gl(4, a, nw) = elnuc_dist_gl(4, a)
    +
    +        en_rescaled_single_gl(4, a, nw) = en_rescaled_single_gl(4, a, nw) + kappa_l
    +
    +        en_rescaled_single_gl(1, a, nw) = en_rescaled_single_gl(1, a, nw)  * dexp(kappa_l * single_en_distance(a,nw))
    +        en_rescaled_single_gl(2, a, nw) = en_rescaled_single_gl(2, a, nw)  * dexp(kappa_l * single_en_distance(a,nw))
    +        en_rescaled_single_gl(3, a, nw) = en_rescaled_single_gl(3, a, nw)  * dexp(kappa_l * single_en_distance(a,nw))
    +        en_rescaled_single_gl(4, a, nw) = en_rescaled_single_gl(4, a, nw)  * dexp(kappa_l * single_en_distance(a,nw))
    +     end do
    +
    +  end do
    +
    +
    +end function qmckl_compute_en_rescaled_single_gl_doc_f
    +
    +
    +
    +
    +
    + + +
    +

    7.4. Electron-nucleus Jastrow gradients and Laplacian

    +
    +

    +Calculate the gradients and Laplacian of the \(\delta J_{en}\). +

    +\begin{eqnarray*} + \partial_{i,m}\delta J_{en} = & \sum_\alpha \delta_{i,\text{num}} \left( \frac{a_1 \partial_{i,m}\widetilde{R}^{\text{new}}_{i\alpha}}{(1+a_2 \widetilde{R}^{\text{new}}_{i\alpha})^2} - \frac{a_1 \partial_{i,m}\widetilde{R}^{\text{old}}_{i\alpha}}{(1+a_2 \widetilde{R}^{\text{old}}_{i\alpha})^2} + \sum_{k=2}^{N_{\text{aord}}} a_k k \left({\widetilde{R}_{i\alpha}^{\text{new}}}^{k-1} \partial_{i,m}\widetilde{R}^{\text{new}}_{i\alpha} - {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-1} \partial_{i,m}\widetilde{R}^{\text{old}}_{i\alpha} \right) \right)\\ + \partial_{i,4}\delta J_{en} = & \sum_\alpha \delta_{i,\text{num}} \left( \frac{a_1}{(1+a_2 \widetilde{R}^{\text{new}}_{i\alpha})^2} \left(\partial_{i,4}\widetilde{R}^{\text{new}}_{i\alpha} - 2 a_2 \frac{\nabla\widetilde{R}^{\text{new}}_{i\alpha} \cdot \nabla \widetilde{R}^{\text{new}}_{i\alpha}}{1+a_2 \widetilde{R}^{\text{new}}_{i\alpha}} \right) - \frac{a_1}{(1+a_2 \widetilde{R}^{\text{old}}_{i\alpha})^2} \left(\partial_{i,4}\widetilde{R}^{\text{old}}_{i\alpha} - 2 a_2 \frac{\nabla\widetilde{R}^{\text{old}}_{i\alpha} \cdot \nabla \widetilde{R}^{\text{old}}_{i\alpha}}{1+b_2 \widetilde{R}^{\text{old}}_{i\alpha}} \right) \right.\\ + & \left.+ \sum_{k=2}^{N_{\text{aord}}} a_k k \left({\widetilde{R}_{i\alpha}^{\text{new}}}^{k-1}\partial_{i,4}\widetilde{R}_{i\alpha}^{\text{new}} + (k-1)(\nabla\widetilde{R}_{i\alpha}^{\text{new}} \cdot \nabla \widetilde{R}_{i\alpha}^{\text{new}}) {\widetilde{R}_{i\alpha}^{\text{new}}}^{k-2} - {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-1}\partial_{i,4}\widetilde{R}_{i\alpha}^{\text{old}} - (k-1)(\nabla\widetilde{R}_{i\alpha}^{\text{old}} \cdot \nabla \widetilde{R}_{i\alpha}^{\text{old}}) {\widetilde{R}_{i\alpha}^{\text{old}}}^{k-2} \right) \right) +\end{eqnarray*} +
    + +
    +

    7.4.1. Get

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_en_gl(qmckl_context context,
    +                                    double* const delta_en_gl,
    +                                    const int64_t size_max);
    +
    +
    + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_en_gl (context, &
    +        delta_en_gl, size_max) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +     integer(c_int64_t), intent(in), value       :: size_max
    +     real(c_double),   intent(out)               :: delta_en_gl(size_max)
    +   end function qmckl_get_jastrow_champ_single_en_gl
    +end interface
    +
    +
    +
    +
    + +
    +

    7.4.2. Compute

    +
    + + + +++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VariableTypeIn/OutDescription
    contextqmckl_contextinGlobal state
    numint64_tinIndex of single electron
    walk_numint64_tinNumber of walkers
    elec_numint64_tinNumber of electrons
    nucl_numint64_tinNumber of nuclei
    type_nucl_numint64_tinNumber of unique nuclei
    type_nucl_vectorint64_t[nucl_num]inIDs of unique nuclei
    aord_numint64_tinNumber of coefficients
    a_vectordouble[type_nucl_num][aord_num+1]inList of coefficients
    en_distance_rescaleddouble[walk_num][nucl_num][elec_num]inElectron-nucleus rescaled distances
    en_distance_rescaled_gldouble[walk_num][nucl_num][elec_num][4]inElectron-nucleus rescaled distance derivatives
    en_rescaled_singledouble[walk_num][nucl_num]inElectron-nucleus rescaled single distances
    en_rescaled_single_gldouble[walk_num][nucl_num][4]inElectron-nucleus rescaled single distance derivatives
    delta_en_gldouble[walk_num][elec_num][4]outSingle electron-nucleus Jastrow gradients and Laplacian
    + +
    +
    function qmckl_compute_jastrow_champ_single_en_gl_doc( &
    +     context, num_in, walk_num, elec_num, nucl_num, type_nucl_num, &
    +     type_nucl_vector, aord_num, a_vector, &
    +     en_distance_rescaled, en_distance_rescaled_gl, en_rescaled_single, en_rescaled_single_gl, delta_en_gl) &
    +     bind(C) result(info)
    +  use qmckl
    +  implicit none
    +
    +  integer (qmckl_context), intent(in), value :: context
    +  integer (c_int64_t) , intent(in)  , value :: num_in
    +  integer (c_int64_t) , intent(in)  , value :: walk_num
    +  integer (c_int64_t) , intent(in)  , value :: elec_num
    +  integer (c_int64_t) , intent(in)  , value :: nucl_num
    +  integer (c_int64_t) , intent(in)  , value :: type_nucl_num
    +  integer (c_int64_t) , intent(in)          :: type_nucl_vector(nucl_num)
    +  integer (c_int64_t) , intent(in)  , value :: aord_num
    +  real    (c_double ) , intent(in)          :: a_vector(aord_num+1,type_nucl_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled(elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_distance_rescaled_gl(4, elec_num,nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_rescaled_single(nucl_num,walk_num)
    +  real    (c_double ) , intent(in)          :: en_rescaled_single_gl(4, nucl_num,walk_num)
    +  real    (c_double ) , intent(out)         :: delta_en_gl(4,elec_num,walk_num)
    +  integer(qmckl_exit_code)                   :: info
    +
    +  integer*8 :: i, a, k, nw, ii, num
    +  double precision   :: x, x1, kf, x_old, x1_old
    +  double precision   :: denom, invdenom, invdenom2, f
    +  double precision   :: denom_old, invdenom_old, invdenom2_old, f_old
    +  double precision   :: grad_c2, grad_c2_old
    +  double precision   :: dx(4), dx_old(4)
    +
    +  num = num_in + 1
    +
    +  info = QMCKL_SUCCESS
    +
    +  if (context == QMCKL_NULL_CONTEXT) then
    +     info = QMCKL_INVALID_CONTEXT
    +     return
    +  endif
    +
    +  if (walk_num <= 0) then
    +     info = QMCKL_INVALID_ARG_3
    +     return
    +  endif
    +
    +  if (elec_num <= 0) then
    +     info = QMCKL_INVALID_ARG_4
    +     return
    +  endif
    +
    +  if (nucl_num <= 0) then
    +     info = QMCKL_INVALID_ARG_5
    +     return
    +  endif
    +
    +  if (aord_num < 0) then
    +     info = QMCKL_INVALID_ARG_8
    +     return
    +  endif
    +
    +
    +  do nw =1, walk_num
    +    delta_en_gl(:,:,nw) = 0.0d0
    +
    +    do a = 1, nucl_num
    +
    +          x_old = en_distance_rescaled(num,a,nw)
    +          x = en_rescaled_single(a,nw)
    +
    +
    +          denom = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x
    +          invdenom = 1.0d0 / denom
    +          invdenom2 = invdenom*invdenom
    +
    +          denom_old = 1.0d0 + a_vector(2, type_nucl_vector(a)+1) * x_old
    +          invdenom_old = 1.0d0 / denom_old
    +          invdenom2_old = invdenom_old*invdenom_old
    +
    +          dx(1) = en_rescaled_single_gl(1,a,nw)
    +          dx(2) = en_rescaled_single_gl(2,a,nw)
    +          dx(3) = en_rescaled_single_gl(3,a,nw)
    +          dx(4) = en_rescaled_single_gl(4,a,nw)
    +
    +          dx_old(1) = en_distance_rescaled_gl(1,num,a,nw)
    +          dx_old(2) = en_distance_rescaled_gl(2,num,a,nw)
    +          dx_old(3) = en_distance_rescaled_gl(3,num,a,nw)
    +          dx_old(4) = en_distance_rescaled_gl(4,num,a,nw)
    +
    +          f = a_vector(1, type_nucl_vector(a)+1) * invdenom2
    +          grad_c2 = dx(1)*dx(1) + dx(2)*dx(2) + dx(3)*dx(3)
    +
    +          f_old = a_vector(1, type_nucl_vector(a)+1) * invdenom2_old
    +          grad_c2_old = dx_old(1)*dx_old(1) + dx_old(2)*dx_old(2) + dx_old(3)*dx_old(3)
    +
    +          delta_en_gl(1,num,nw) = delta_en_gl(1,num,nw) + f * dx(1) - f_old * dx_old(1)
    +          delta_en_gl(2,num,nw) = delta_en_gl(2,num,nw) + f * dx(2) - f_old * dx_old(2)
    +          delta_en_gl(3,num,nw) = delta_en_gl(3,num,nw) + f * dx(3) - f_old * dx_old(3)
    +          delta_en_gl(4,num,nw) = delta_en_gl(4,num,nw) &
    +               + f * (dx(4) - 2.d0 * a_vector(2, type_nucl_vector(a)+1) * grad_c2 * invdenom) &
    +               - f_old * (dx_old(4) - 2.d0 * a_vector(2, type_nucl_vector(a)+1) * grad_c2_old * invdenom_old)
    +
    +
    +           kf = 2.d0
    +           x1 = x
    +           x = 1.d0
    +           x1_old = x_old
    +           x_old = 1.d0
    +           do k=2, aord_num
    +              f = a_vector(k+1,type_nucl_vector(a)+1) * kf * x
    +              f_old = a_vector(k+1,type_nucl_vector(a)+1) * kf * x_old
    +              delta_en_gl(1,num,nw) = delta_en_gl(1,num,nw) + f * x1 * dx(1) - f_old * x1_old * dx_old(1)
    +              delta_en_gl(2,num,nw) = delta_en_gl(2,num,nw) + f * x1 * dx(2) - f_old * x1_old * dx_old(2)
    +              delta_en_gl(3,num,nw) = delta_en_gl(3,num,nw) + f * x1 * dx(3) - f_old * x1_old * dx_old(3)
    +              delta_en_gl(4,num,nw) = delta_en_gl(4,num,nw) &
    +                   + f * (x1 * dx(4) + (kf-1.d0) * grad_c2) &
    +                   - f_old * (x1_old * dx_old(4) + (kf-1.d0) * grad_c2_old)
    +              x = x*x1
    +              x_old = x_old*x1_old
    +              kf = kf + 1.d0
    +           end do
    +     end do
    +  end do
    +
    +end function qmckl_compute_jastrow_champ_single_en_gl_doc
    +
    +
    +
    +
    +
    +
    + +
    +

    8. Accept single electron move

    +
    +

    +This function 'accepts' a proposed single-electron move. It overrides (or adds to) the required arrays and matrices to bring the positions of the electron and the full Jastrow factor up to date. +For instances, +

    +\begin{eqnarray} +J_{en} = & J_{en} + \delta J_{en}\\ +J_{ee} = & J_{ee} + \delta J_{ee}\\ +J_{een} = & J_{een} + \delta J_{een}\\ + +\partial_{i,m} J_{en} = & \partial_{i,m} J_{en} + \partial_{i,m} \delta J_{en}\\ +\partial_{i,m} J_{ee} = & \partial_{i,m} J_{ee} + \partial_{i,m} \delta J_{ee}\\ +\partial_{i,m} J_{een} = & \partial_{i,m} J_{een} + \partial_{i,m} \delta J_{een}\\ + +\end{eqnarray} +

    +The function has similar functionaly for the intermediate products, such as \(P\), \(\widetilde{r}\), \(\widetilde{R}\), and the derivative of these. +Furthermore, it also updates the dates, such that immidiatly calling a Jastrow function after an accepted single-electron move will not trigger a re-calculation of the Jastrow factors. +

    +
    + +
    +

    8.1. Code

    +
    +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_accept(qmckl_context context);
    +
    +
    + +
    +
    qmckl_exit_code
    +qmckl_get_jastrow_champ_single_accept(qmckl_context context)
    +{
    +
    +  if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
    +    return QMCKL_NULL_CONTEXT;
    +  }
    +
    +  qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
    +  assert (ctx != NULL);
    +
    +  qmckl_exit_code rc;
    +
    +  rc = qmckl_provide_jastrow_champ_single_en_gl(context);
    +  if (rc != QMCKL_SUCCESS) return rc;
    +
    +  rc = qmckl_provide_jastrow_champ_single_ee_gl(context);
    +  if (rc != QMCKL_SUCCESS) return rc;
    +
    +  if (ctx->jastrow_champ.cord_num > 0) {
    +    rc = qmckl_provide_jastrow_champ_single_een_gl(context);
    +    if (rc != QMCKL_SUCCESS) return rc;
    +  }
    +
    +  double metric[4] = {-1.0, -1.0, -1.0, 1.0};
    +
    +  int shift1, shift2, shift3, shift4, shift5, shift6, shift7;
    +
    +  int shift8, shift9, shift10, shift11, shift12, shift13, shift14;
    +
    +  shift2 = ctx->electron.num*ctx->electron.num;
    +  shift5 = ctx->electron.num*4*ctx->electron.num;
    +  shift6 = ctx->electron.num*4;
    +  shift11 = ctx->nucleus.num*4*ctx->electron.num;
    +  shift13 = ctx->nucleus.num*4;
    +  shift14 = ctx->nucleus.num*ctx->electron.num;
    +
    +
    +  if (ctx->jastrow_champ.cord_num > 0) {
    +
    +    shift1 = (ctx->jastrow_champ.cord_num+1)*ctx->electron.num*ctx->electron.num;
    +
    +    shift3 = (ctx->jastrow_champ.cord_num+1)*ctx->electron.num;
    +
    +    shift4 = (ctx->jastrow_champ.cord_num+1)*ctx->electron.num*4*ctx->electron.num;
    +
    +    shift7 = (ctx->jastrow_champ.cord_num+1)*ctx->electron.num*4;
    +
    +    shift8 = (ctx->jastrow_champ.cord_num+1)*ctx->nucleus.num*ctx->electron.num;
    +    shift9 = (ctx->jastrow_champ.cord_num+1)*ctx->nucleus.num;
    +
    +    shift10 = (ctx->jastrow_champ.cord_num+1)*ctx->nucleus.num*4*ctx->electron.num;
    +
    +    shift12 = (ctx->jastrow_champ.cord_num+1)*ctx->nucleus.num*4;
    +
    +    for (int nw = 0; nw < ctx->electron.walker.num; nw++) {
    +      ctx->jastrow_champ.factor_een[nw] = ctx->jastrow_champ.factor_een[nw] + ctx->single_point.delta_een[nw];
    +      for (int l = 0; l <= ctx->jastrow_champ.cord_num; l++){
    +        for (int i = 0; i < ctx->electron.num; i++) {
    +          ctx->jastrow_champ.een_rescaled_e[nw*shift1
    +            + l*shift2 
    +            + i*ctx->electron.num 
    +            + ctx->single_point.num] = 
    +          ctx->single_point.een_rescaled_single_e[nw*shift3
    +            + l*ctx->electron.num
    +            + i];
    +
    +          ctx->jastrow_champ.een_rescaled_e[nw*shift1
    +            + l*shift2
    +            + ctx->single_point.num*ctx->electron.num 
    +            + i] = 
    +          ctx->single_point.een_rescaled_single_e[nw*shift3
    +            + l*ctx->electron.num
    +            + i];
    +          for (int k = 0; k < 4; k++){
    +            ctx->jastrow_champ.een_rescaled_e_gl[nw*shift4
    +              + l*shift5
    +              + i*shift6
    +              + k*ctx->electron.num 
    +              + ctx->single_point.num] = 
    +            ctx->single_point.een_rescaled_single_e_gl[nw*shift7
    +              + l*shift6
    +              + i*4 
    +              + k]; 
    +            ctx->jastrow_champ.een_rescaled_e_gl[nw*shift4
    +              + l*shift5
    +              + ctx->single_point.num*shift6
    +              + k*ctx->electron.num 
    +              + i] = 
    +            metric[k] * ctx->single_point.een_rescaled_single_e_gl[nw*shift7
    +              + l*shift6
    +              + i*4
    +              + k]; 
    +          }
    +        }
    +        for (int a = 0; a < ctx->nucleus.num; a++){
    +          ctx->jastrow_champ.een_rescaled_n[nw*shift8
    +            + l*shift14
    +            + a*ctx->electron.num
    +            + ctx->single_point.num] = 
    +          ctx->single_point.een_rescaled_single_n[nw*shift9
    +            + l*ctx->nucleus.num
    +            + a];
    +          for (int k = 0; k < 4; k++){
    +            ctx->jastrow_champ.een_rescaled_n_gl[nw*shift10
    +              + l*shift11
    +              + a*shift6
    +              + k*ctx->electron.num
    +              + ctx->single_point.num] = 
    +            ctx->single_point.een_rescaled_single_n_gl[nw*shift12
    +              + l*shift13
    +              + a*4
    +              + k];
    +          }
    +        }
    +      }
    +    }
    +    for (int i = 0; i < ctx->electron.walker.num * 4 * ctx->electron.num; i++) {
    +      ctx->jastrow_champ.factor_een_gl[i] = ctx->jastrow_champ.factor_een_gl[i] + ctx->single_point.delta_een_gl[i];
    +    }  
    +    for (int i = 0; i < (ctx->electron.walker.num*(ctx->jastrow_champ.cord_num+1)*ctx->nucleus.num*ctx->electron.num*ctx->jastrow_champ.cord_num); i++) {
    +     ctx->jastrow_champ.tmp_c[i] = ctx->jastrow_champ.tmp_c[i] + ctx->single_point.delta_p[i];
    +    }
    +
    +/*
    +    for (int nw = 0; nw < ctx->electron.walker.num; nw++) {
    +      for (int m = 0; m < ctx->jastrow_champ.cord_num; m++){
    +        for (int l = 0; l <= ctx->jastrow_champ.cord_num; l++) {
    +          for (int a = 0; a < ctx->nucleus.num; a++) {
    +            for (int k = 0; k < 4; k++){
    +              for (int i = 0; i < ctx->electron.num; i++) {
    +                ctx->jastrow_champ.dtmp_c[nw*ctx->electron.num*4*ctx->nucleus.num*ctx->jastrow_champ.cord_num*(ctx->jastrow_champ.cord_num+1)
    +                  + m*ctx->electron.num*4*ctx->nucleus.num*(ctx->jastrow_champ.cord_num+1)
    +                  + l*ctx->electron.num*4*ctx->nucleus.num
    +                  + a*4*ctx->electron.num
    +                  + k*ctx->electron.num
    +                  + i] =
    +                ctx->jastrow_champ.dtmp_c[nw*ctx->electron.num*4*ctx->nucleus.num*ctx->jastrow_champ.cord_num*(ctx->jastrow_champ.cord_num+1)
    +                  + m*ctx->electron.num*4*ctx->nucleus.num*(ctx->jastrow_champ.cord_num+1)
    +                  + l*ctx->electron.num*4*ctx->nucleus.num
    +                  + a*4*ctx->electron.num
    +                  + k*ctx->electron.num
    +                  + i] +
    +                ctx->single_point.delta_p_gl[nw*ctx->electron.num*4*ctx->nucleus.num*ctx->jastrow_champ.cord_num*(ctx->jastrow_champ.cord_num+1)
    +                  + m*ctx->electron.num*4*ctx->nucleus.num*(ctx->jastrow_champ.cord_num+1)
    +                  + l*ctx->electron.num*4*ctx->nucleus.num
    +                  + k*ctx->electron.num*ctx->nucleus.num
    +                  + a*ctx->electron.num
    +                  + i];
    +              }
    +            }
    +          }
    +        }
    +      }
    +    }
    +
    +*/
    +
    +    for (int nw = 0; nw < ctx->electron.walker.num*(ctx->jastrow_champ.cord_num+1)*ctx->jastrow_champ.cord_num; nw++) {
    +      for (int a = 0; a < ctx->nucleus.num; a++) {
    +        for (int k = 0; k < 4; k++){
    +          for (int i = 0; i < ctx->electron.num; i++) {
    +            ctx->jastrow_champ.dtmp_c[nw*shift11
    +              + a*shift6
    +              + k*ctx->electron.num
    +              + i] =
    +            ctx->jastrow_champ.dtmp_c[nw*shift11
    +              + a*shift6
    +              + k*ctx->electron.num
    +              + i] +
    +            ctx->single_point.delta_p_gl[nw*shift11
    +              + k*shift14
    +              + a*ctx->electron.num
    +              + i];
    +          }
    +        }
    +      }
    +    }
    +  }
    +
    +
    +  for (int nw = 0; nw < ctx->electron.walker.num; nw++) {
    +    ctx->jastrow_champ.factor_en[nw] = ctx->jastrow_champ.factor_en[nw] + ctx->single_point.delta_en[nw];
    +    ctx->jastrow_champ.factor_ee[nw] = ctx->jastrow_champ.factor_ee[nw] + ctx->single_point.delta_ee[nw];
    +    for (int a = 0; a < ctx->nucleus.num; a++) {
    +      ctx->electron.en_distance[nw*shift14
    +        + ctx->single_point.num*ctx->nucleus.num
    +        + a] =
    +      ctx->single_point.single_en_distance[nw*ctx->nucleus.num
    +        + a];
    +
    +      ctx->jastrow_champ.en_distance_rescaled[nw*shift14
    +        + a*ctx->electron.num
    +        + ctx->single_point.num] =
    +      ctx->single_point.en_rescaled_single[nw*ctx->nucleus.num
    +        + a];
    +      for (int k = 0; k < 4; k++){
    +        ctx->jastrow_champ.en_distance_rescaled_gl[nw*shift11
    +          + a*shift6
    +          + ctx->single_point.num*4
    +          + k] = 
    +        ctx->single_point.en_rescaled_single_gl[nw*shift13
    +          + a*4
    +          + k];
    +      }
    +    }
    +    for (int i = 0; i < ctx->electron.num; i++) {
    +      ctx->jastrow_champ.ee_distance_rescaled[nw*shift2
    +        + i*ctx->electron.num
    +        + ctx->single_point.num] =
    +      ctx->single_point.ee_rescaled_single[nw*ctx->electron.num
    +        + i];
    +
    +      ctx->jastrow_champ.ee_distance_rescaled[nw*shift2
    +        + ctx->single_point.num*ctx->electron.num
    +        + i] =
    +      ctx->single_point.ee_rescaled_single[nw*ctx->electron.num
    +        + i];
    +
    +      ctx->electron.ee_distance[nw*shift2
    +        + i*ctx->electron.num
    +        + ctx->single_point.num] =
    +      ctx->single_point.single_ee_distance[nw*ctx->electron.num
    +        + i];
    +
    +      ctx->electron.ee_distance[nw*shift2
    +        + ctx->single_point.num*ctx->electron.num
    +        + i] =
    +      ctx->single_point.single_ee_distance[nw*ctx->electron.num
    +        + i];
    +
    +      for (int k = 0; k < 4; k++){
    +        ctx->jastrow_champ.ee_distance_rescaled_gl[nw*shift5
    +          + i*shift6
    +          + ctx->single_point.num*4 
    +          + k] = 
    +        metric[k] * ctx->single_point.ee_rescaled_single_gl[nw*shift6
    +          + i*4 
    +          + k];
    +        ctx->jastrow_champ.ee_distance_rescaled_gl[nw*shift5
    +          + ctx->single_point.num*shift6
    +          + i*4 
    +          + k] =  
    +        ctx->single_point.ee_rescaled_single_gl[nw*shift6
    +          + i*4 
    +          + k];
    +      }
    +    }
    +    for (int k = 0; k < 4; k++){
    +      for (int i = 0; i < ctx->electron.num; i++) {
    +
    +        ctx->jastrow_champ.factor_ee_gl[nw*shift6
    +          + k*ctx->electron.num
    +          + i] = 
    +        ctx->jastrow_champ.factor_ee_gl[nw*shift6
    +          + k*ctx->electron.num
    +          + i] + 
    +        ctx->single_point.delta_ee_gl[nw*shift6
    +          + i*4
    +          + k];
    +
    +        ctx->jastrow_champ.factor_en_gl[nw*shift6
    +          + k*ctx->electron.num
    +          + i] = 
    +        ctx->jastrow_champ.factor_en_gl[nw*shift6
    +          + k*ctx->electron.num
    +          + i] + 
    +        ctx->single_point.delta_en_gl[nw*shift6
    +          + i*4
    +          + k];
    +      }
    +    }
    +  }
    +
    +  for (int nw = 0; nw < ctx->electron.walker.num; nw++) {
    +    for (int k = 0; k < 3; k++) {
    +      ctx->point.coord.data[k*ctx->electron.walker.num*ctx->electron.num + nw*ctx->electron.num + ctx->single_point.num] = ctx->single_point.coord.data[nw*3 + k];
    +    }
    +  }
    +
    +  rc = qmckl_context_touch(context);
    +  if (rc != QMCKL_SUCCESS) return rc;
    +
    +
    +  if (ctx->jastrow_champ.cord_num > 0){
    +    ctx->jastrow_champ.dtmp_c_date = ctx->date;
    +    ctx->jastrow_champ.een_rescaled_e_date = ctx->date;
    +    ctx->jastrow_champ.een_rescaled_e_gl_date = ctx->date;
    +    ctx->jastrow_champ.een_rescaled_n_date = ctx->date;
    +    ctx->jastrow_champ.een_rescaled_n_gl_date = ctx->date;
    +    ctx->jastrow_champ.factor_een_date = ctx->date;
    +    ctx->jastrow_champ.factor_een_gl_date = ctx->date;
    +    ctx->jastrow_champ.tmp_c_date = ctx->date;
    +
    +  }
    +  ctx->jastrow_champ.ee_distance_rescaled_date = ctx->date;
    +  ctx->jastrow_champ.ee_distance_rescaled_gl_date = ctx->date;
    +  ctx->jastrow_champ.en_distance_rescaled_date = ctx->date;
    +  ctx->jastrow_champ.en_distance_rescaled_gl_date = ctx->date;
    +  ctx->jastrow_champ.factor_ee_date = ctx->date;
    +  ctx->jastrow_champ.factor_ee_gl_date = ctx->date;
    +  ctx->jastrow_champ.factor_en_date = ctx->date;
    +  ctx->jastrow_champ.factor_en_gl_date = ctx->date;
    +
    +  ctx->electron.ee_distance_date = ctx->date;
    +  ctx->electron.en_distance_date = ctx->date;
    +
    +  ctx->single_point.date = ctx->date;
    +
    +  if (ctx->jastrow_champ.cord_num > 0){
    +    ctx->single_point.een_rescaled_single_e_date = ctx->single_point.date;
    +    ctx->single_point.een_rescaled_single_n_date = ctx->single_point.date;
    +    ctx->single_point.delta_een_date = ctx->single_point.date;
    +    ctx->single_point.delta_p_date = ctx->single_point.date;
    +    ctx->single_point.een_rescaled_single_e_gl_date = ctx->single_point.date;
    +    ctx->single_point.een_rescaled_single_n_gl_date = ctx->single_point.date;
    +    ctx->single_point.delta_p_gl_date = ctx->single_point.date;
    +    ctx->single_point.delta_een_gl_date = ctx->single_point.date;
    +    ctx->single_point.delta_p_g_date = ctx->single_point.date;
    +    ctx->single_point.delta_een_g_date = ctx->single_point.date;
    +    ctx->forces.forces_delta_p_date = ctx->single_point.date;
    +    ctx->forces.forces_jastrow_single_een_date = ctx->single_point.date;
    +  }
    +  ctx->single_point.single_ee_distance_date = ctx->single_point.date;
    +  ctx->single_point.single_en_distance_date = ctx->single_point.date;
    +  ctx->single_point.ee_rescaled_single_date = ctx->single_point.date;
    +  ctx->single_point.en_rescaled_single_date = ctx->single_point.date;
    +  ctx->single_point.delta_en_date = ctx->single_point.date;
    +  ctx->single_point.delta_ee_date = ctx->single_point.date;
    +  ctx->single_point.ee_rescaled_single_gl_date = ctx->single_point.date;
    +  ctx->single_point.en_rescaled_single_gl_date = ctx->single_point.date;
    +  ctx->single_point.delta_en_gl_date = ctx->single_point.date;
    +  ctx->single_point.delta_ee_gl_date = ctx->single_point.date;
    +  ctx->forces.forces_jastrow_single_en_date = ctx->single_point.date;
    +
    +
    +  return QMCKL_SUCCESS;
    +}
    +
    +
    + + +
    +
    interface
    +   integer(qmckl_exit_code) function qmckl_get_jastrow_champ_single_accept (context) bind(C)
    +     use, intrinsic :: iso_c_binding
    +     import
    +     implicit none
    +     integer (qmckl_context) , intent(in), value :: context
    +   end function qmckl_get_jastrow_champ_single_accept
    +end interface
    +
    +
    +
    +
    +
    +
    +
    +

    Author: TREX CoE

    +

    Created: 2025-04-29 Tue 08:44

    +

    Validate

    +
    + + diff --git a/qmckl_local_energy.html b/qmckl_local_energy.html index d2e5b59..a6f4bc3 100644 --- a/qmckl_local_energy.html +++ b/qmckl_local_energy.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Local Energy @@ -258,44 +258,44 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following arrays are stored in the context: @@ -378,8 +378,8 @@ Computed data:

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    typedef struct qmckl_local_energy_struct {
    @@ -413,8 +413,8 @@ this mechanism.
     
    -
    -

    1.2. Access functions

    +
    +

    1.2. Access functions

    When all the data for the local energy have been provided, the following @@ -429,12 +429,12 @@ function returns true.

    -
    -

    2. Computation

    +
    +

    2. Computation

    -
    -

    2.1. Kinetic energy

    +
    +

    2.1. Kinetic energy

    Where the kinetic energy is given as: @@ -458,8 +458,8 @@ case is given as follows:

    -
    -

    2.1.1. Get

    +
    +

    2.1.1. Get

    qmckl_exit_code qmckl_get_kinetic_energy(qmckl_context context, double* const kinetic_energy);
    @@ -468,14 +468,14 @@ case is given as follows:
     
    -
    -

    2.1.2. Provide

    +
    +

    2.1.2. Provide

    -
    -

    2.1.3. Compute kinetic enregy

    +
    +

    2.1.3. Compute kinetic enregy

    - +
    @@ -704,12 +704,12 @@ case is given as follows: -
    -

    2.1.4. Test

    +
    +

    2.1.4. Test

    -
    -

    2.2. Potential energy

    +
    +

    2.2. Potential energy

    The potential energy is the sum of all the following terms @@ -745,8 +745,8 @@ contributions.

    -
    -

    2.2.1. Get

    +
    +

    2.2.1. Get

    qmckl_exit_code qmckl_get_potential_energy(qmckl_context context, double* const potential_energy);
    @@ -755,14 +755,14 @@ contributions.
     
    -
    -

    2.2.2. Provide

    +
    +

    2.2.2. Provide

    -
    -

    2.2.3. Compute potential enregy

    +
    +

    2.2.3. Compute potential enregy

    -
    +
    @@ -889,12 +889,12 @@ contributions. -
    -

    2.2.4. Test

    +
    +

    2.2.4. Test

    -
    -

    2.3. Local energy

    +
    +

    2.3. Local energy

    The local energy is the sum of kinetic and potential energies. @@ -908,8 +908,8 @@ E_L = KE + PE

    -
    -

    2.3.1. Get

    +
    +

    2.3.1. Get

    qmckl_exit_code qmckl_get_local_energy(qmckl_context context, double* const local_energy, const int64_t size_max);
    @@ -918,14 +918,14 @@ E_L = KE + PE
     
    -
    -

    2.3.2. Provide

    +
    +

    2.3.2. Provide

    -
    -

    2.3.3. Compute local enregy

    +
    +

    2.3.3. Compute local enregy

    -
    +
    @@ -1021,12 +1021,12 @@ E_L = KE + PE -
    -

    2.3.4. Test

    +
    +

    2.3.4. Test

    -
    -

    2.4. Drift vector

    +
    +

    2.4. Drift vector

    The drift vector is calculated as the ration of the gradient @@ -1040,8 +1040,8 @@ with the determinant of the wavefunction.

    -
    -

    2.4.1. Get

    +
    +

    2.4.1. Get

    qmckl_exit_code qmckl_get_drift_vector(qmckl_context context, double* const drift_vector);
    @@ -1050,14 +1050,14 @@ with the determinant of the wavefunction.
     
    -
    -

    2.4.2. Provide

    +
    +

    2.4.2. Provide

    -
    -

    2.4.3. Compute drift vector

    +
    +

    2.4.3. Compute drift vector

    -
    +
    @@ -1278,15 +1278,15 @@ with the determinant of the wavefunction. -
    -

    2.4.4. Test

    +
    +

    2.4.4. Test

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_memory.html b/qmckl_memory.html index 4e14063..0ffbfda 100644 --- a/qmckl_memory.html +++ b/qmckl_memory.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - +Memory management @@ -226,16 +226,16 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Memory data structure for the context

    +
    +

    1. Memory data structure for the context

    Every time a new block of memory is allocated, the information @@ -277,8 +277,8 @@ array, and the number of allocated blocks.

    -
    -

    2. Passing info to allocation routines

    +
    +

    2. Passing info to allocation routines

    Passing information to the allocation routine should be done by @@ -287,8 +287,8 @@ passing an instance of a qmckl_memory_info_struct.

    -
    -

    3. Allocation/deallocation functions

    +
    +

    3. Allocation/deallocation functions

    Memory allocation inside the library should be done with @@ -547,8 +547,8 @@ successful deallocation of the memory block.

    -
    -

    4. Get the size of a memory block

    +
    +

    4. Get the size of a memory block

    All the blocks allocated with qmckl_malloc keep track of how many @@ -643,7 +643,7 @@ rc = qmckl_context_destroy(context);

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_mo.html b/qmckl_mo.html index cd7894c..eff3757 100644 --- a/qmckl_mo.html +++ b/qmckl_mo.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Molecular Orbitals @@ -258,72 +258,72 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following arrays are stored in the context: @@ -402,8 +402,8 @@ Computed data:

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    typedef struct qmckl_mo_basis_struct {
    @@ -460,8 +460,8 @@ this mechanism.
     
    -
    -

    1.2. Initialization functions

    +
    +

    1.2. Initialization functions

    To set the basis set, all the following functions need to be @@ -482,8 +482,8 @@ computed to accelerate the calculations.

    -
    -

    1.3. Cusp adjsutment functions

    +
    +

    1.3. Cusp adjsutment functions

    To activate the cusp adjustment, the user must enter the radius of @@ -498,8 +498,8 @@ of the non-\(s\) AOs at the center.

    -
    -

    1.4. Access functions

    +
    +

    1.4. Access functions

    When all the data for the AOs have been provided, the following @@ -512,13 +512,13 @@ function returns true.

    -
    -

    1.4.1. Fortran interfaces

    +
    +

    1.4.1. Fortran interfaces

    -
    -

    1.5. Update

    +
    +

    1.5. Update

    It may be desirable to remove certain molecular orbitals (MOs) that @@ -545,25 +545,25 @@ calculation. If the integer is non-zero, the MO will be kept.

    -
    -

    1.5.1. Fortran interface

    +
    +

    1.5.1. Fortran interface

    -
    -

    2. Computation

    +
    +

    2. Computation

    -
    -

    2.1. Parameters of the cusp-correction functions

    +
    +

    2.1. Parameters of the cusp-correction functions

    -
    -

    2.2. Computation of MOs: values only

    +
    +

    2.2. Computation of MOs: values only

    -
    -

    2.2.1. Get

    +
    +

    2.2.1. Get

    qmckl_exit_code
    @@ -587,8 +587,8 @@ Uses the given array to compute the values.
     
    -
    -

    2.2.2. Provide

    +
    +

    2.2.2. Provide

    qmckl_exit_code qmckl_provide_mo_basis_mo_value(qmckl_context context);
    @@ -671,10 +671,10 @@ Uses the given array to compute the values.
     
    -
    -

    2.2.3. Compute

    +
    +

    2.2.3. Compute

    - +
    @@ -829,8 +829,8 @@ matrix multiplication instead of a dgemm, as exposed in -
    -

    2.2.4. HPC version

    +
    +

    2.2.4. HPC version

    #ifdef HAVE_HPC
    @@ -857,8 +857,8 @@ matrix multiplication instead of a dgemm, as exposed in
     
    -
    -
    2.2.4.1. Single-precision
    +
    +
    2.2.4.1. Single-precision
    #ifdef HAVE_HPC
    @@ -979,8 +979,8 @@ matrix multiplication instead of a dgemm, as exposed in
     
    -
    -
    2.2.4.2. Double-precision
    +
    +
    2.2.4.2. Double-precision
    #ifdef HAVE_HPC
    @@ -1097,12 +1097,12 @@ matrix multiplication instead of a dgemm, as exposed in
     
    -
    -

    2.3. Computation of MOs: values, gradient, Laplacian

    +
    +

    2.3. Computation of MOs: values, gradient, Laplacian

    -
    -

    2.3.1. Get

    +
    +

    2.3.1. Get

    qmckl_exit_code
    @@ -1126,8 +1126,8 @@ Uses the given array to compute the VGL.
     
    -
    -

    2.3.2. Provide

    +
    +

    2.3.2. Provide

    qmckl_exit_code qmckl_provide_mo_basis_mo_vgl(qmckl_context context);
    @@ -1209,10 +1209,10 @@ Uses the given array to compute the VGL.
     
    -
    -

    2.3.3. Compute

    +
    +

    2.3.3. Compute

    -
    +
    @@ -1381,14 +1381,14 @@ matrix multiplication instead of a dgemm, as exposed in -
    -

    2.4. Computation of cusp-corrected MOs: values only

    +
    +

    2.4. Computation of cusp-corrected MOs: values only

    -
    -

    2.4.1. Compute

    +
    +

    2.4.1. Compute

    -
    +
    @@ -1627,8 +1627,8 @@ matrix multiplication instead of a dgemm, as exposed in -
    -

    2.4.2. HPC version

    +
    +

    2.4.2. HPC version

    #ifdef HAVE_HPC
    @@ -1766,14 +1766,14 @@ IVDEP
     
    -
    -

    2.5. Computation of cusp-corrected MOs: values, gradient, Laplacian

    +
    +

    2.5. Computation of cusp-corrected MOs: values, gradient, Laplacian

    -
    -

    2.5.1. Compute

    +
    +

    2.5.1. Compute

    -
    +
    @@ -2073,8 +2073,8 @@ IVDEP -
    -

    2.5.2. HPC version

    +
    +

    2.5.2. HPC version

    #ifdef HAVE_HPC
    @@ -2273,8 +2273,8 @@ IVDEP
     
    -
    -

    2.6. Rescaling of MO coefficients

    +
    +

    2.6. Rescaling of MO coefficients

    When evaluating Slater determinants, the value of the determinants @@ -2291,19 +2291,19 @@ correct range.

    -
    -

    2.6.1. Fortran interface

    +
    +

    2.6.1. Fortran interface

    -
    -

    2.7. Test

    +
    +

    2.7. Test

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_nucleus.html b/qmckl_nucleus.html index 07bd92f..a8458b7 100644 --- a/qmckl_nucleus.html +++ b/qmckl_nucleus.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Nucleus @@ -258,28 +258,28 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following data stored in the context: @@ -386,8 +386,8 @@ Computed data:

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    typedef struct qmckl_nucleus_struct {
    @@ -441,8 +441,8 @@ this mechanism.
     
    -
    -

    1.2. Access functions

    +
    +

    1.2. Access functions

    When all the data relative to nuclei have been set, the following @@ -456,8 +456,8 @@ function returns true.

    -
    -

    1.3. Initialization functions

    +
    +

    1.3. Initialization functions

    To set the data relative to the nuclei in the context, the @@ -503,8 +503,8 @@ are be given in atomic units.

    -
    -

    1.4. Test

    +
    +

    1.4. Test

    const double*   nucl_charge   = chbrclf_charge;
    @@ -573,8 +573,8 @@ rc = qmckl_get_nucleus_charge(context, nucl_charge2, chbrclf_nucl_num);
     
    -
    -

    2. Computation

    +
    +

    2. Computation

    The computed data is stored in the context so that it can be reused @@ -587,12 +587,12 @@ current date is stored.

    -
    -

    2.1. Nucleus-nucleus distances

    +
    +

    2.1. Nucleus-nucleus distances

    -
    -

    2.1.1. Get

    +
    +

    2.1.1. Get

    qmckl_exit_code
    @@ -604,10 +604,10 @@ current date is stored.
     
    -
    -

    2.1.2. Compute

    +
    +

    2.1.2. Compute

    - +
    @@ -685,8 +685,8 @@ current date is stored. -
    -

    2.1.3. Test

    +
    +

    2.1.3. Test

    /* Reference input data */
    @@ -705,8 +705,8 @@ rc = qmckl_get_nucleus_nn_distance(context, distance, chbrclf_nucl_num*chbrclf_n
     
    -
    -

    2.2. Nuclear repulsion energy

    +
    +

    2.2. Nuclear repulsion energy

    \[ @@ -715,8 +715,8 @@ rc = qmckl_get_nucleus_nn_distance(context, distance, chbrclf_nucl_num*chbrclf_n

    -
    -

    2.2.1. Get

    +
    +

    2.2.1. Get

    qmckl_exit_code qmckl_get_nucleus_repulsion(qmckl_context context, double* const energy);
    @@ -725,10 +725,10 @@ rc = qmckl_get_nucleus_nn_distance(context, distance, chbrclf_nucl_num*chbrclf_n
     
    -
    -

    2.2.2. Compute

    +
    +

    2.2.2. Compute

    -
    +
    @@ -818,8 +818,8 @@ rc = qmckl_get_nucleus_nn_distance(context, distance, chbrclf_nucl_num*chbrclf_n -
    -

    2.2.3. Test

    +
    +

    2.2.3. Test

    /* Reference input data */
    @@ -839,7 +839,7 @@ rc = qmckl_get_nucleus_repulsion(context, &rep);
     

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_numprec.html b/qmckl_numprec.html index f6d25d9..1657158 100644 --- a/qmckl_numprec.html +++ b/qmckl_numprec.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + @@ -257,18 +257,18 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    @@ -278,8 +278,8 @@ org_html_manager.setup(); // activate after the parameters are set 3+TITLE: Numerical precision

    -
    -

    1. Control of the numerical precision

    +
    +

    1. Control of the numerical precision

    Controlling numerical precision enables optimizations. Here, the @@ -290,7 +290,7 @@ Arithmetic (IEEE 754), sign bit) and range refers to the number of exponent bits.

    -
    +
    @@ -334,8 +334,8 @@ integer. The update functions return QMCKL_SUCCESS or -
    -

    2. Precision

    +
    +

    2. Precision

    qmckl_context_set_numprec_precision modifies the parameter for the @@ -422,8 +422,8 @@ numerical precision in the context.

    -
    -

    3. Range

    +
    +

    3. Range

    qmckl_set_numprec_range modifies the parameter for the numerical @@ -498,12 +498,12 @@ range in a given context.

    -
    -

    4. Helper functions

    +
    +

    4. Helper functions

    -
    -

    4.1. Epsilon

    +
    +

    4.1. Epsilon

    qmckl_get_numprec_epsilon returns \(\epsilon = 2^{1-n}\) where n is the precision. @@ -522,8 +522,8 @@ We need to remove the sign bit from the precision.

    -
    -

    4.2. Testing the number of unchanged bits

    +
    +

    4.2. Testing the number of unchanged bits

    To test that a given approximation keeps a given number of bits @@ -593,12 +593,12 @@ numbers differ.

    -
    -

    5. Approximate functions

    +
    +

    5. Approximate functions

    -
    -

    5.1. Exponential

    +
    +

    5.1. Exponential

    Fast exponential function, adapted from Johan Rade's implementation @@ -653,7 +653,7 @@ N. Schraudolph, "A Fast, Compact Approximation of the Exponential Function",

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_point.html b/qmckl_point.html index 7ddd5f9..ca2f11f 100644 --- a/qmckl_point.html +++ b/qmckl_point.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Point @@ -258,25 +258,25 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Context

    +
    +

    1. Context

    The following data stored in the context: @@ -326,8 +326,8 @@ corresponds to the 3 × num matrix.

    -
    -

    1.1. Data structure

    +
    +

    1.1. Data structure

    typedef struct qmckl_point_struct {
    @@ -363,8 +363,8 @@ corresponds to the 3 × num matrix.
     
    -
    -

    1.2. Access functions

    +
    +

    1.2. Access functions

    Access functions return QMCKL_SUCCESS when the data has been @@ -375,8 +375,8 @@ contains the requested data. Otherwise, this variable is untouched.

    -
    -

    1.2.1. Number of points

    +
    +

    1.2.1. Number of points

    Returns the number of points stored in the context. @@ -398,8 +398,8 @@ Returns the number of points stored in the context.

    -
    -

    1.2.2. Point coordinates

    +
    +

    1.2.2. Point coordinates

    Returns the point coordinates as sequences of (x,y,z). @@ -427,8 +427,8 @@ The pointer is assumed to point on a memory block of size

    -
    -

    1.3. Initialization functions

    +
    +

    1.3. Initialization functions

    When the data is set in the context, if the arrays are large @@ -567,8 +567,8 @@ Copy a sequence of num points \((x,y,z)\) into the context.

    -
    -

    1.4. Test

    +
    +

    1.4. Test

    /* Reference input data */
    @@ -627,7 +627,7 @@ rc = qmckl_get_point (context, 'N', coord3,
     

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_sherman_morrison_woodbury.html b/qmckl_sherman_morrison_woodbury.html index 32a4ca7..d5e5ea6 100644 --- a/qmckl_sherman_morrison_woodbury.html +++ b/qmckl_sherman_morrison_woodbury.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Sherman-Morrison-Woodbury @@ -258,118 +258,118 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Headers

    +
    +

    1. Headers

    #include "qmckl.h"
    @@ -391,17 +391,17 @@ This is the range that determines the how many high performance kernel instantce
     

    -
    -

    2. Naïve Sherman-Morrison

    +
    +

    2. Naïve Sherman-Morrison

    -
    -

    2.1. qmckl_sm_naive

    +
    +

    2.1. qmckl_sm_naive

    -
    -

    2.1.1. Introduction

    +
    +

    2.1.1. Introduction

    This is the simplest of the available Sherman-Morrison-Woodbury kernels. It applies rank-1 updates one by one in @@ -451,10 +451,10 @@ from applying the updates to the original matrix.

    -
    -

    2.1.2. API

    +
    +

    2.1.2. API

    -
    +
    @@ -542,8 +542,8 @@ from applying the updates to the original matrix. -
    -

    2.1.3. Requirements

    +
    +

    2.1.3. Requirements

    • context is not QMCKL_NULL_CONTEXT
    • @@ -559,8 +559,8 @@ from applying the updates to the original matrix.
    -
    -

    2.1.4. Pedagogical kernel source (in Fortran)

    +
    +

    2.1.4. Pedagogical kernel source (in Fortran)

    The following source code written in Fortran is inteded to illustrate how the kernel works. Even though the kernel is @@ -654,8 +654,8 @@ not be used in real workloads.

    -
    -
    2.1.4.1. C interface (not directly exposed)
    +
    +
    2.1.4.1. C interface (not directly exposed)

    The following Fortran function qmckl_sm_naive_doc makes sure @@ -667,8 +667,8 @@ for C users and in the module file 'qmcklf.F90' for Fortran users.

    -
    -

    2.1.5. C headers (exposed in qmckl.h)

    +
    +

    2.1.5. C headers (exposed in qmckl.h)

    qmckl_exit_code qmckl_sm_naive (
    @@ -714,8 +714,8 @@ for C users and in the module file 'qmcklf.F90' for Fortran users.
     
    -
    -

    2.1.6. C sources

    +
    +

    2.1.6. C sources

    Common includes and macros used by all the Sherman-Morrison-Woodbury kernels. @@ -817,7 +817,7 @@ multiple of SIMD_LENGTH. qmckl_exit_code qmckl_sm_naive_{Dim} is a C function-template that is used to genereate instances of C fucntions based on the range given above. The advantage of this method is that for each of these instances all the dimensions and loop-bounds are known at compile time, allowing the compiler to optimize more aggressively.

    -
    static inline qmckl_exit_code qmckl_sm_naive_{Dim}(
    +
    static inline qmckl_exit_code qmckl_sm_naive_{Dim}(
         const qmckl_context context,
         const uint64_t N_updates,
         const double* restrict Updates,
    @@ -893,7 +893,7 @@ multiple of SIMD_LENGTH.
     This is the kernel generator written in Python. It uses the kernel generator range and templates defined above to generate the C kernel instances.
     

    -
    text="""
    +
    text="""
     static inline qmckl_exit_code qmckl_sm_naive_{Dim}(
         const qmckl_context context,
         const uint64_t N_updates,
    @@ -977,7 +977,7 @@ This is the kernel generator written in Python. It uses the kernel generator ran
     Python script that generated C switch cases that call individual kernel instances.
     

    -
    text="""
    +
    text="""
     case {Dim}:  
       return qmckl_sm_naive_{Dim}(context,
         N_updates,
    @@ -2618,14 +2618,14 @@ Python script that generated C switch cases that call individual kernel instance
     
    -
    -

    2.1.7. Fortran interfaces (exposed in qmcklf.F90)

    +
    +

    2.1.7. Fortran interfaces (exposed in qmcklf.F90)

    -
    -

    2.1.8. Performance

    +
    +

    2.1.8. Performance

    This function performs best when there is only 1 rank-1 update in the update cycle. It is @@ -2634,8 +2634,8 @@ can never resolve a situation where applying the update causes singular behaviou

    -
    -

    2.1.9. Tests

    +
    +

    2.1.9. Tests

    The tests for the kernels are executed on datasets that are extracted from a run of @@ -2703,17 +2703,17 @@ rc = QMCKL_SUCCESS;

    -
    -

    3. Sherman-Morrison with Slagel Splitting (core)

    +
    +

    3. Sherman-Morrison with Slagel Splitting (core)

    -
    -

    3.1. qmckl_sm_splitting_core

    +
    +

    3.1. qmckl_sm_splitting_core

    -
    -

    3.1.1. Introduction

    +
    +

    3.1.1. Introduction

    qmckl_sm_splitting_core is the inner core part of 'Sherman-Morrison with update splitting' in the next section. @@ -2741,10 +2741,10 @@ If the determinant is passed it will only be partially updated if there were any

    -
    -

    3.1.2. API

    +
    +

    3.1.2. API

    -
    +
    @@ -2853,8 +2853,8 @@ If the determinant is passed it will only be partially updated if there were any -
    -

    3.1.3. Requirements

    +
    +

    3.1.3. Requirements

    • LDS >= 2
    • @@ -2871,8 +2871,8 @@ If the determinant is passed it will only be partially updated if there were any
    -
    -

    3.1.4. Pedagogical kernel source (in Fortran)

    +
    +

    3.1.4. Pedagogical kernel source (in Fortran)

    The following source code written in Fortran is inteded to illustrate how the kernel works. Even though the kernel is @@ -2988,8 +2988,8 @@ not be used in real workloads.

    -
    -
    3.1.4.1. C interface to the pedagogical kernel (not directly exposed)
    +
    +
    3.1.4.1. C interface to the pedagogical kernel (not directly exposed)

    The function qmckl_sm_splitting_core_doc makes sure that @@ -3002,8 +3002,8 @@ exposed in qmckl.h and qmckl_f.F90, but

    -
    -

    3.1.5. C headers (exposed in qmckl.h)

    +
    +

    3.1.5. C headers (exposed in qmckl.h)

    qmckl_exit_code qmckl_sm_splitting_core (
    @@ -3058,8 +3058,8 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    3.1.6. C sources

    +
    +

    3.1.6. C sources

    qmckl_exit_code qmckl_sm_splitting_core_hpc(
    @@ -3148,7 +3148,7 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    static inline qmckl_exit_code qmckl_sm_splitting_core_{Dim}(
    +
    static inline qmckl_exit_code qmckl_sm_splitting_core_{Dim}(
         const qmckl_context context,
         uint64_t N_updates,
         const double* restrict Updates,
    @@ -3232,7 +3232,7 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    text="""
    +
    text="""
     static inline qmckl_exit_code qmckl_sm_splitting_core_{Dim}(
         const qmckl_context context,
         uint64_t N_updates,
    @@ -3324,7 +3324,7 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    text="""
    +
    text="""
     case {Dim}: {
       return qmckl_sm_splitting_core_{Dim}(
           context,
    @@ -5292,14 +5292,14 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    3.1.7. Fortran interfaces (exposed in qmcklf.F90)

    +
    +

    3.1.7. Fortran interfaces (exposed in qmcklf.F90)

    -
    -

    3.1.8. Performance

    +
    +

    3.1.8. Performance

    This function cannot be used by itself and is used in Sherman-Morrison with update splitting and Woodbury 3x3 and 2x2 @@ -5311,17 +5311,17 @@ with Sherman-Morrison and update splitting. Please look at the performance recco

    -
    -

    4. Woodbury 2x2

    +
    +

    4. Woodbury 2x2

    -
    -

    4.1. qmckl_woodbury_2x2

    +
    +

    4.1. qmckl_woodbury_2x2

    -
    -

    4.1.1. Introduction

    +
    +

    4.1.1. Introduction

    The Woodbury 2x2 kernel. It is used to apply two rank-1 updates at once. The formula used in @@ -5345,10 +5345,10 @@ from applying the updates to the original matrix.

    -
    -

    4.1.2. API

    +
    +

    4.1.2. API

    -
    +
    @@ -5429,8 +5429,8 @@ from applying the updates to the original matrix. -
    -

    4.1.3. Requirements

    +
    +

    4.1.3. Requirements

    • context is not qmckl_null_context
    • @@ -5444,8 +5444,8 @@ from applying the updates to the original matrix.
    -
    -

    4.1.4. Pedagogical kernel source (in Fortran)

    +
    +

    4.1.4. Pedagogical kernel source (in Fortran)

    The following source code written in Fortran is inteded to illustrate how the kernel works. Even though the kernel is @@ -5581,8 +5581,8 @@ not be used in real workloads.

    -
    -
    4.1.4.1. C interface (not directly exposed)
    +
    +
    4.1.4.1. C interface (not directly exposed)

    The function qmckl_sm_splitting_core_doc makes sure that @@ -5595,8 +5595,8 @@ exposed in qmckl.h and qmckl_f.F90, but

    -
    -

    4.1.5. C headers (exposed in qmckl.h)

    +
    +

    4.1.5. C headers (exposed in qmckl.h)

    qmckl_exit_code qmckl_woodbury_2x2 (
    @@ -5639,8 +5639,8 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    4.1.6. C sources

    +
    +

    4.1.6. C sources

    qmckl_exit_code qmckl_woodbury_2x2_hpc(const qmckl_context context,
    @@ -5724,7 +5724,7 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    static inline qmckl_exit_code qmckl_woodbury_2x2_{Dim}(
    +
    static inline qmckl_exit_code qmckl_woodbury_2x2_{Dim}(
         const qmckl_context context,
         const double* restrict Updates,
         const uint64_t* restrict Updates_index,
    @@ -7674,14 +7674,14 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    4.1.7. Fortran interfaces (exposed in qmcklf.F90)

    +
    +

    4.1.7. Fortran interfaces (exposed in qmcklf.F90)

    -
    -

    4.1.8. Performance

    +
    +

    4.1.8. Performance

    This function is most efficient when used in cases where there are only 2 rank-1 updates and @@ -7690,8 +7690,8 @@ it is sure they will not result in a singular matrix.

    -
    -

    4.1.9. Tests

    +
    +

    4.1.9. Tests

    assert(Updates2 != NULL);
    @@ -7728,17 +7728,17 @@ rc = QMCKL_SUCCESS;
     
    -
    -

    5. Woodbury 3x3

    +
    +

    5. Woodbury 3x3

    -
    -

    5.1. qmckl_woodbury_3x3

    +
    +

    5.1. qmckl_woodbury_3x3

    -
    -

    5.1.1. Introduction

    +
    +

    5.1.1. Introduction

    The Woodbury 3x3 kernel. It is used to apply two rank-1 updates at once. The formula used in @@ -7762,10 +7762,10 @@ from applying the updates to the original matrix.

    -
    -

    5.1.2. API

    +
    +

    5.1.2. API

    -
    +
    @@ -7846,8 +7846,8 @@ from applying the updates to the original matrix. -
    -

    5.1.3. Requirements

    +
    +

    5.1.3. Requirements

    • context is not qmckl_null_context
    • @@ -7861,8 +7861,8 @@ from applying the updates to the original matrix.
    -
    -

    5.1.4. Pedagogical kernel source (in Fortran)

    +
    +

    5.1.4. Pedagogical kernel source (in Fortran)

    The following source code written in Fortran is inteded to illustrate how the kernel works. Even though the kernel is @@ -8007,8 +8007,8 @@ not be used in real workloads.

    -
    -
    5.1.4.1. C interface (not directly exposed)
    +
    +
    5.1.4.1. C interface (not directly exposed)

    The function qmckl_sm_splitting_core_doc makes sure that @@ -8021,8 +8021,8 @@ exposed in qmckl.h and qmckl_f.F90, but

    -
    -

    5.1.5. C headers (exposed in qmckl.h)

    +
    +

    5.1.5. C headers (exposed in qmckl.h)

    qmckl_exit_code qmckl_woodbury_3x3 (
    @@ -8065,8 +8065,8 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    5.1.6. C sources

    +
    +

    5.1.6. C sources

    qmckl_exit_code qmckl_woodbury_3x3_hpc(const qmckl_context context,
    @@ -8176,7 +8176,7 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    static inline qmckl_exit_code qmckl_woodbury_3x3_{Dim}(
    +
    static inline qmckl_exit_code qmckl_woodbury_3x3_{Dim}(
         const qmckl_context context,
         const double* restrict Updates,
         const uint64_t* restrict Updates_index,
    @@ -10546,14 +10546,14 @@ exposed in qmckl.h and qmckl_f.F90, but
     
    -
    -

    5.1.7. Fortran interfaces (exposed in qmcklf.F90)

    +
    +

    5.1.7. Fortran interfaces (exposed in qmcklf.F90)

    -
    -

    5.1.8. Performance

    +
    +

    5.1.8. Performance

    This function is most efficient when used in cases where there are only 3 rank-1 updates and @@ -10562,8 +10562,8 @@ it is sure they will not result in a singular matrix.

    -
    -

    5.1.9. Tests

    +
    +

    5.1.9. Tests

    assert(Updates3 != NULL);
    @@ -10600,17 +10600,17 @@ rc = QMCKL_SUCCESS;
     
    -
    -

    6. Sherman-Morrison with Slagel Splitting

    +
    +

    6. Sherman-Morrison with Slagel Splitting

    -
    -

    6.1. qmckl_sm_splitting

    +
    +

    6.1. qmckl_sm_splitting

    -
    -

    6.1.1. Introduction

    +
    +

    6.1.1. Introduction

    This is a variation on the 'Naive' Sherman-Morrison kernel. Whenever the denominator \(1+v_j^T S^{-1} u_j\) in @@ -10634,10 +10634,10 @@ from applying the updates to the original matrix.

    -
    -

    6.1.2. API

    +
    +

    6.1.2. API

    -
    +
    @@ -10725,8 +10725,8 @@ from applying the updates to the original matrix. -
    -

    6.1.3. Requirements

    +
    +

    6.1.3. Requirements

    • context is not QMCKL_NULL_CONTEXT
    • @@ -10741,8 +10741,8 @@ from applying the updates to the original matrix.
    -
    -

    6.1.4. Pedagogical kernel source (in Fortran)

    +
    +

    6.1.4. Pedagogical kernel source (in Fortran)

    The following source code written in Fortran is inteded to illustrate how the kernel works. Even though the kernel is @@ -10821,8 +10821,8 @@ not be used in real workloads.

    -
    -
    6.1.4.1. C interface to the pedagogical kernel (not directly exposed)
    +
    +
    6.1.4.1. C interface to the pedagogical kernel (not directly exposed)

    The following Fortran function qmckl_sm_splitting_core_doc makes sure @@ -10835,8 +10835,8 @@ for C users and in the module file 'qmcklf.F90' for Fortran users.

    -
    -

    6.1.5. C headers (exposed in qmckl.h)

    +
    +

    6.1.5. C headers (exposed in qmckl.h)

    qmckl_exit_code qmckl_sm_splitting (
    @@ -10882,11 +10882,11 @@ for C users and in the module file 'qmcklf.F90' for Fortran users.
     
    -
    -

    6.1.6. C source

    +
    +

    6.1.6. C source

    -
    text="""
    +
    text="""
     case {Dim}: {
       rc = qmckl_sm_splitting_core_{Dim}(
           context,
    @@ -11289,14 +11289,14 @@ for C users and in the module file 'qmcklf.F90' for Fortran users.
     
    -
    -

    6.1.7. Fortran interfaces (exposed in qmcklf.F90)

    +
    +

    6.1.7. Fortran interfaces (exposed in qmcklf.F90)

    -
    -

    6.1.8. Performance…

    +
    +

    6.1.8. Performance…

    This kernel performs best when there are 2 or more rank-1 update cycles and fail-rate is high. @@ -11304,8 +11304,8 @@ This kernel performs best when there are 2 or more rank-1 update cycles and fail

    -
    -

    6.1.9. Test

    +
    +

    6.1.9. Test

    assert(Updates3 != NULL);
    @@ -11343,8 +11343,8 @@ rc = QMCKL_SUCCESS;
     
     
     
    -
    -

    7. End of files

    +
    +

    7. End of files

    assert (qmckl_context_destroy(context) == QMCKL_SUCCESS);
    @@ -11358,7 +11358,7 @@ rc = QMCKL_SUCCESS;
     

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_tests.html b/qmckl_tests.html index fb4a82b..d4a2e65 100644 --- a/qmckl_tests.html +++ b/qmckl_tests.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Data for Tests @@ -200,27 +200,27 @@

    Table of Contents

    -
    -

    1. CHBrClF

    +
    +

    1. CHBrClF

    This test is the all-electron Hartree-Fock wave function of CHClBr, @@ -231,7 +231,7 @@ and with a high maximum angular momentum.

    -
    +

    chbrclf.png

    @@ -304,10 +304,10 @@ and with a high maximum angular momentum.
    -
    -

    1.1. XYZ coordinates

    +
    +

    1.1. XYZ coordinates

    -
    +
       5
     CHBrClF
      C         0.580107    0.471341    0.411546
    @@ -335,10 +335,10 @@ Nuclear coordinates are stored in atomic units in transposed format.
     
    -
    -

    1.2. Atomic basis set

    +
    +

    1.2. Atomic basis set

    -
    +
     HYDROGEN
     S   5
     1         3.387000E+01           6.068000E-03
    @@ -1255,8 +1255,8 @@ F   1
     
    -
    -

    1.3. Molecular orbitals

    +
    +

    1.3. Molecular orbitals

    #define chbrclf_mo_num ((int64_t) 224)
    @@ -1270,8 +1270,8 @@ F   1
     
    -
    -

    1.4. Electron coordinates

    +
    +

    1.4. Electron coordinates

    Electron coordinates are stored in atomic units in normal format. @@ -1430,8 +1430,8 @@ Electron coordinates are stored in atomic units in normal format.

    -
    -

    2. N2

    +
    +

    2. N2

    This test is mainly for the Jastrow factor and was supplied by @@ -1472,10 +1472,10 @@ treated by pseudopotentials thus excluded from the actual calculation.

    -
    -

    2.1. XYZ coordinates

    +
    +

    2.1. XYZ coordinates

    -
    +
       2
     N2
      N         0.000000    0.000000    0.00
    @@ -1500,8 +1500,8 @@ Nuclear coordinates are stored in atomic units in transposed format.
     
    -
    -

    2.2. Electron coordinates

    +
    +

    2.2. Electron coordinates

    Electron coordinates are stored in atomic units in normal format. @@ -1540,8 +1540,8 @@ Electron coordinates are stored in atomic units in normal format.

    -
    -

    2.3. Jastrow related data

    +
    +

    2.3. Jastrow related data

    This test is mainly for the Jastrow factor and was supplied by @@ -1640,7 +1640,7 @@ Ramon Panades Baruetta.

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_trexio.html b/qmckl_trexio.html index 3fab785..27ff348 100644 --- a/qmckl_trexio.html +++ b/qmckl_trexio.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + TREXIO I/O library @@ -226,53 +226,53 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Local functions

    +
    +

    1. Local functions

    Functions defined in this section are all local: they should not be @@ -305,8 +305,8 @@ In the functions defined in this section, we use as local variables

    -
    -

    1.1. Open file

    +
    +

    1.1. Open file

    We first define a helper function to open a file by first trying to @@ -344,8 +344,8 @@ groups of data by passing the trexio_t handle.

    -
    -

    1.2. Electron

    +
    +

    1.2. Electron

    In this section we read all the data into the electron data structure. @@ -396,8 +396,8 @@ We read the number of up-spin and down-spin electrons.

    -
    -

    1.3. Nucleus

    +
    +

    1.3. Nucleus

    In this section we read the number of nuclei, the molecular geometry and nuclear charges. @@ -417,8 +417,8 @@ In this section we read the number of nuclei, the molecular geometry and nuclear

    -
    -

    1.3.1. Number of nuclei

    +
    +

    1.3.1. Number of nuclei

    int64_t nucleus_num = 0L;
    @@ -441,8 +441,8 @@ rc = qmckl_set_nucleus_num(context, nucleus_num);
     
    -
    -

    1.3.2. Nuclear charges

    +
    +

    1.3.2. Nuclear charges

    {
    @@ -482,8 +482,8 @@ rc = qmckl_set_nucleus_num(context, nucleus_num);
     
    -
    -

    1.3.3. Nuclear coordinates

    +
    +

    1.3.3. Nuclear coordinates

    Now, we read the molecular geometry. It is stored in normal format @@ -538,8 +538,8 @@ in the TREXIO file ('N'), so it will be automatically transposed in

    -
    -

    1.4. Basis set and AOs

    +
    +

    1.4. Basis set and AOs

    In this section we read the atomic basis set and atomic orbitals. @@ -565,8 +565,8 @@ In this section we read the atomic basis set and atomic orbitals.

    -
    -

    1.4.1. Basis set type

    +
    +

    1.4.1. Basis set type

    #define MAX_STR_LEN 1024
    @@ -597,8 +597,8 @@ In this section we read the atomic basis set and atomic orbitals.
     
    -
    -

    1.4.2. Number of shells

    +
    +

    1.4.2. Number of shells

    int64_t shell_num = 0L;
    @@ -622,8 +622,8 @@ rc = qmckl_set_ao_basis_shell_num(context, shell_num);
     
    -
    -

    1.4.3. Number of primitives

    +
    +

    1.4.3. Number of primitives

    int64_t prim_num = 0L;
    @@ -647,8 +647,8 @@ rc = qmckl_set_ao_basis_prim_num(context, prim_num);
     
    -
    -

    1.4.4. Number of atomic orbitals

    +
    +

    1.4.4. Number of atomic orbitals

    int64_t ao_num = 0;
    @@ -672,8 +672,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.5. Nucleusindex array

    +
    +

    1.4.5. Nucleusindex array

    {
    @@ -753,8 +753,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.6. Number of shells per nucleus

    +
    +

    1.4.6. Number of shells per nucleus

    {
    @@ -839,8 +839,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.7. Angular momentum

    +
    +

    1.4.7. Angular momentum

    {
    @@ -885,8 +885,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.8. Number of primitives per shell

    +
    +

    1.4.8. Number of primitives per shell

    {
    @@ -972,8 +972,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.9. Indices of the primitives

    +
    +

    1.4.9. Indices of the primitives

    {
    @@ -1053,8 +1053,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.10. Normalization of the shells

    +
    +

    1.4.10. Normalization of the shells

    {
    @@ -1099,8 +1099,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.11. Exponents

    +
    +

    1.4.11. Exponents

    {
    @@ -1145,8 +1145,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.12. Coefficients

    +
    +

    1.4.12. Coefficients

    {
    @@ -1191,8 +1191,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.13. Normalization of the primitivies

    +
    +

    1.4.13. Normalization of the primitivies

    {
    @@ -1237,8 +1237,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.4.14. AO Normalization

    +
    +

    1.4.14. AO Normalization

    {
    @@ -1293,8 +1293,8 @@ rc = qmckl_set_ao_basis_ao_num(context, ao_num);
     
    -
    -

    1.5. Molecular orbitals

    +
    +

    1.5. Molecular orbitals

    In this section we read the MO coefficients. @@ -1320,8 +1320,8 @@ In this section we read the MO coefficients.

    -
    -

    1.5.1. Number of MOs

    +
    +

    1.5.1. Number of MOs

    int64_t mo_num = 0L;
    @@ -1344,8 +1344,8 @@ rc = qmckl_set_mo_basis_mo_num(context, mo_num);
     
    -
    -

    1.5.2. MO coefficients

    +
    +

    1.5.2. MO coefficients

    {
    @@ -1394,12 +1394,12 @@ rc = qmckl_set_mo_basis_mo_num(context, mo_num);
     
    -
    -

    1.6. TODO ECP

    +
    +

    1.6. TODO ECP

    -
    -

    2. Read everything

    +
    +

    2. Read everything

    qmckl_exit_code
    @@ -1474,8 +1474,8 @@ rc = qmckl_set_mo_basis_mo_num(context, mo_num);
     
    -
    -

    3. Test

    +
    +

    3. Test

    #ifdef HAVE_TREXIO
    @@ -1499,8 +1499,8 @@ rc = qmckl_trexio_read(context, filename, 255);
     
    -
    -

    3.0.1. Electrons

    +
    +

    3.0.1. Electrons

    printf("Electrons\n");
    @@ -1518,8 +1518,8 @@ rc = qmckl_get_electron_down_num(context, &dn_num);
     
    -
    -

    3.0.2. Nuclei

    +
    +

    3.0.2. Nuclei

    printf("Nuclei\n");
    @@ -1559,8 +1559,8 @@ coord = NULL;
     
    -
    -

    3.0.3. Atomic basis

    +
    +

    3.0.3. Atomic basis

    printf("Atomic basis\n");
    @@ -1668,8 +1668,8 @@ prim_factor = NULL;
     
    -
    -

    3.0.4. MO Basis

    +
    +

    3.0.4. MO Basis

    printf("MOs\n");
    @@ -1700,7 +1700,7 @@ charge = NULL;
     

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate

    diff --git a/qmckl_verificarlo.html b/qmckl_verificarlo.html index f3edbbb..cff1e12 100644 --- a/qmckl_verificarlo.html +++ b/qmckl_verificarlo.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Verificarlo CI @@ -226,22 +226,22 @@ org_html_manager.setup(); // activate after the parameters are set

    Table of Contents

    -
    -

    1. Verificarlo probes

    +
    +

    1. Verificarlo probes

    This file contains utility functions to enable the Verificarlo @@ -292,8 +292,8 @@ To learn more about Verificarlo CI :

    -
    -

    1.1. Automatically initialize the vfc_probe object if VFC_CI is defined

    +
    +

    1.1. Automatically initialize the vfc_probe object if VFC_CI is defined

    void qmckl_init_probes();
    @@ -311,8 +311,8 @@ To learn more about Verificarlo CI :
     
    -
    -

    1.2. Standard probe, without check

    +
    +

    1.2. Standard probe, without check

    • if VFC_CI is defined, place a standard probe
    • @@ -347,8 +347,8 @@ if VFC_CI is undefined, return false (no error)
    -
    -

    1.3. Probe with absolute check

    +
    +

    1.3. Probe with absolute check

    • if VFC_CI is defined, place a probe with an absolute check
    • @@ -388,8 +388,8 @@ and accuracy
    -
    -

    1.4. Probe with relative check

    +
    +

    1.4. Probe with relative check

    • if VFC_CI is defined, place a probe with a relative check
    • @@ -429,8 +429,8 @@ and accuracy
    -
    -

    1.5. Automatically delete and dump the vfcprobe object if VFC_CI is defined

    +
    +

    1.5. Automatically delete and dump the vfcprobe object if VFC_CI is defined

    void qmckl_dump_probes();
    @@ -449,8 +449,8 @@ and accuracy
     
    -
    -

    2. Fortran wrappers

    +
    +

    2. Fortran wrappers

    bool qmckl_probe_f(
    @@ -574,7 +574,7 @@ and accuracy
     

    Author: TREX CoE

    -

    Created: 2025-04-02 Wed 13:00

    +

    Created: 2025-04-29 Tue 08:44

    Validate