mirror of
https://github.com/TREX-CoE/qmckl.git
synced 2024-08-17 02:41:43 +02:00
Added AO basis in context. Tests to do
This commit is contained in:
parent
8a53306a63
commit
6b797bd5d4
188
src/README.org
188
src/README.org
@ -1,58 +1,53 @@
|
|||||||
#+TITLE: QMCkl source code documentation
|
#+TITLE: QMCkl source code documentation
|
||||||
#+EXPORT_FILE_NAME: index.html
|
#+EXPORT_FILE_NAME: index.html
|
||||||
|
|
||||||
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
|
#+SETUPFILE: https://fniessen.github.io/org-html-themes/setup/theme-readtheorg.setup
|
||||||
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
|
|
||||||
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
|
||||||
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
|
||||||
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
|
|
||||||
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
|
|
||||||
|
|
||||||
* Introduction
|
* Introduction
|
||||||
|
|
||||||
The ultimate goal of QMCkl is to provide a high-performance
|
The ultimate goal of QMCkl is to provide a high-performance
|
||||||
implementation of the main kernels of QMC. In this particular
|
implementation of the main kernels of QMC. In this particular
|
||||||
repository, we focus on the definition of the API and the tests,
|
repository, we focus on the definition of the API and the tests, and
|
||||||
and on a /pedagogical/ presentation of the algorithms. We expect the
|
on a /pedagogical/ presentation of the algorithms. We expect the
|
||||||
HPC experts to use this repository as a reference for re-writing
|
HPC experts to use this repository as a reference for re-writing
|
||||||
optimized libraries.
|
optimized libraries.
|
||||||
|
|
||||||
Literate programming is particularly adapted in this context.
|
Literate programming is particularly adapted in this context.
|
||||||
Source files are written in [[https://karl-voit.at/2017/09/23/orgmode-as-markup-only/][org-mode]] format, to provide useful
|
Source files are written in [[https://karl-voit.at/2017/09/23/orgmode-as-markup-only/][org-mode]] format, to provide useful
|
||||||
comments and LaTex formulas close to the code. There exists multiple
|
comments and LaTex formulas close to the code. There exists multiple
|
||||||
possibilities to convert org-mode files into different formats such as
|
possibilities to convert org-mode files into different formats such
|
||||||
HTML or pdf.
|
as HTML or pdf. For a tutorial on literate programming with
|
||||||
For a tutorial on literate programming with org-mode, follow
|
org-mode, follow [[http://www.howardism.org/Technical/Emacs/literate-programming-tutorial.html][this link]].
|
||||||
[[http://www.howardism.org/Technical/Emacs/literate-programming-tutorial.html][this link]].
|
|
||||||
|
|
||||||
The code is extracted from the org files using Emacs as a command-line
|
The code is extracted from the org files using Emacs as a
|
||||||
tool in the =Makefile=, and then the produced files are compiled.
|
command-line tool in the =Makefile=, and then the produced files are
|
||||||
|
compiled.
|
||||||
|
|
||||||
** Language used
|
** Language used
|
||||||
|
|
||||||
Fortran is one of the most common languages used by the community,
|
Fortran is one of the most common languages used by the community,
|
||||||
and is simple enough to make the algorithms readable. Hence we
|
and is simple enough to make the algorithms readable. Hence we
|
||||||
propose in this pedagogical implementation of QMCkl to use Fortran
|
propose in this pedagogical implementation of QMCkl to use Fortran
|
||||||
to express the algorithms. For specific internal functions where
|
to express the algorithms. For specific internal functions where
|
||||||
the C language is more natural, C is used.
|
the C language is more natural, C is used.
|
||||||
|
|
||||||
As Fortran modules generate compiler-dependent files, the use of
|
As Fortran modules generate compiler-dependent files, the use of
|
||||||
modules is restricted to the internal use of the library, otherwise
|
modules is restricted to the internal use of the library, otherwise
|
||||||
the compliance with C is violated.
|
the compliance with C is violated.
|
||||||
|
|
||||||
The external dependencies should be kept as small as possible, so
|
The external dependencies should be kept as small as possible, so
|
||||||
external libraries should be used /only/ if their used is strongly
|
external libraries should be used /only/ if their used is strongly
|
||||||
justified.
|
justified.
|
||||||
|
|
||||||
** Source code editing
|
** Source code editing
|
||||||
|
|
||||||
Any text editor can be used to edit org-mode files. For a better
|
Any text editor can be used to edit org-mode files. For a better
|
||||||
user experience Emacs is recommended.
|
user experience Emacs is recommended. For users hating Emacs, it
|
||||||
For users hating Emacs, it is good to know that Emacs can behave
|
is good to know that Emacs can behave like Vim when switched into
|
||||||
like Vim when switched into ``Evil'' mode. There also exists
|
``Evil'' mode. There also exists [[https://www.spacemacs.org][Spacemacs]] which helps the
|
||||||
[[https://www.spacemacs.org][Spacemacs]] which helps the transition for Vim users.
|
transition for Vim users.
|
||||||
|
|
||||||
For users with a preference for Jupyter notebooks, the following
|
For users with a preference for Jupyter notebooks, the following
|
||||||
script can convert jupyter notebooks to org-mode files:
|
script can convert jupyter notebooks to org-mode files:
|
||||||
|
|
||||||
#+BEGIN_SRC sh tangle: nb_to_org.sh
|
#+BEGIN_SRC sh tangle: nb_to_org.sh
|
||||||
@ -72,24 +67,25 @@ rm ${nb}.md
|
|||||||
|
|
||||||
** Writing in Fortran
|
** Writing in Fortran
|
||||||
|
|
||||||
The Fortran source files should provide a C interface using
|
The Fortran source files should provide a C interface using
|
||||||
=iso_c_binding=. The name of the Fortran source files should end
|
=iso_c_binding=. The name of the Fortran source files should end
|
||||||
with =_f.f90= to be properly handled by the Makefile.
|
with =_f.f90= to be properly handled by the Makefile. The names of
|
||||||
The names of the functions defined in fortran should be the same as
|
the functions defined in fortran should be the same as those
|
||||||
those exposed in the API suffixed by =_f=.
|
exposed in the API suffixed by =_f=. Fortran interface files
|
||||||
Fortran interface files should also be written in a file with a
|
should also be written in the =qmckl_f.f90= file.
|
||||||
=.fh= extension.
|
|
||||||
|
|
||||||
For more guidelines on using Fortran to generate a C interface, see
|
For more guidelines on using Fortran to generate a C interface, see
|
||||||
[[http://fortranwiki.org/fortran/show/Generating+C+Interfaces][this link]]
|
[[http://fortranwiki.org/fortran/show/Generating+C+Interfaces][this link]].
|
||||||
|
|
||||||
** Coding style
|
** Coding style
|
||||||
# TODO: decide on a coding style
|
# TODO: decide on a coding style
|
||||||
|
|
||||||
To improve readability, we maintain a consistent coding style in the library.
|
To improve readability, we maintain a consistent coding style in
|
||||||
|
the library.
|
||||||
|
|
||||||
- For C source files, we will use __(decide on a coding style)__
|
- For C source files, we will use __(decide on a coding style)__
|
||||||
- For Fortran source files, we will use __(decide on a coding style)__
|
- For Fortran source files, we will use __(decide on a coding
|
||||||
|
style)__
|
||||||
|
|
||||||
Coding style can be automatically checked with [[https://clang.llvm.org/docs/ClangFormat.html][clang-format]].
|
Coding style can be automatically checked with [[https://clang.llvm.org/docs/ClangFormat.html][clang-format]].
|
||||||
|
|
||||||
@ -99,103 +95,105 @@ rm ${nb}.md
|
|||||||
- deal with memory transfers between CPU and accelerators
|
- deal with memory transfers between CPU and accelerators
|
||||||
- use different levels of floating-point precision
|
- use different levels of floating-point precision
|
||||||
|
|
||||||
We chose a multi-layered design with low-level and high-level
|
We chose a multi-layered design with low-level and high-level
|
||||||
functions (see below).
|
functions (see below).
|
||||||
|
|
||||||
*** Naming conventions
|
*** Naming conventions
|
||||||
|
|
||||||
Use =qmckl_= as a prefix for all exported functions and variables.
|
Use =qmckl_= as a prefix for all exported functions and variables.
|
||||||
All exported header files should have a filename with the prefix
|
All exported header files should have a filename with the prefix
|
||||||
=qmckl_=.
|
=qmckl_=.
|
||||||
|
|
||||||
If the name of the org-mode file is =xxx.org=, the name of the
|
If the name of the org-mode file is =xxx.org=, the name of the
|
||||||
produced C files should be =xxx.c= and =xxx.h= and the name of the
|
produced C files should be =xxx.c= and =xxx.h= and the name of the
|
||||||
produced Fortran files should be =xxx.f90=
|
produced Fortran files should be =xxx.f90=
|
||||||
|
|
||||||
Arrays are in uppercase and scalars are in lowercase.
|
Arrays are in uppercase and scalars are in lowercase.
|
||||||
|
|
||||||
|
In the names of the variables and functions, only the singular
|
||||||
|
form is allowed.
|
||||||
|
|
||||||
*** Application programming interface
|
*** Application programming interface
|
||||||
|
|
||||||
The application programming interface (API) is designed to be
|
The application programming interface (API) is designed to be
|
||||||
compatible with the C programming language (not C++), to ensure
|
compatible with the C programming language (not C++), to ensure
|
||||||
that the library will be easily usable in any language.
|
that the library will be easily usable in /any/ language. This
|
||||||
This implies that only the following data types are allowed in the API:
|
implies that only the following data types are allowed in the API:
|
||||||
|
|
||||||
- 32-bit and 64-bit floats and arrays (=real= and =double=)
|
- 32-bit and 64-bit floats and arrays (=real= and =double=)
|
||||||
- 32-bit and 64-bit integers and arrays (=int32_t= and =int64_t=)
|
- 32-bit and 64-bit integers and arrays (=int32_t= and =int64_t=)
|
||||||
- Pointers should be represented as 64-bit integers (even on
|
- Pointers should be represented as 64-bit integers (even on
|
||||||
32-bit architectures)
|
32-bit architectures)
|
||||||
- ASCII strings are represented as a pointers to a character arrays
|
- ASCII strings are represented as a pointers to a character
|
||||||
and terminated by a zero character (C convention).
|
arrays and terminated by a zero character (C convention).
|
||||||
|
|
||||||
Complex numbers can be represented by an array of 2 floats.
|
Complex numbers can be represented by an array of 2 floats.
|
||||||
|
|
||||||
# TODO : Link to repositories for bindings
|
# TODO : Link to repositories for bindings
|
||||||
To facilitate the use in other languages than C, we provide some
|
To facilitate the use in other languages than C, we provide some
|
||||||
bindings in other languages in other repositories.
|
bindings in other languages in other repositories.
|
||||||
|
|
||||||
*** Global state
|
*** Global state
|
||||||
|
|
||||||
Global variables should be avoided in the library, because it is
|
Global variables should be avoided in the library, because it is
|
||||||
possible that one single program needs to use multiple instances of
|
possible that one single program needs to use multiple instances
|
||||||
the library. To solve this problem we propose to use a pointer to a
|
of the library. To solve this problem we propose to use a pointer
|
||||||
=context= variable, built by the library with the
|
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
|
state of the library, and is used as the first argument of many
|
||||||
QMCkl functions.
|
QMCkl functions.
|
||||||
|
|
||||||
Modifying the state is done by setters and getters, prefixed
|
The internal structure of the context is not specified, to give a
|
||||||
by =qmckl_context_set_= an =qmckl_context_get_=.
|
maximum of freedom to the different implementations. Modifying
|
||||||
When a context variable is modified by a setter, a copy of the old
|
the state is done by setters and getters, prefixed by
|
||||||
data structure is made and updated, and the pointer to the new data
|
=qmckl_context_set_= an =qmckl_context_get_=. When a context
|
||||||
structure is returned, such that the old contexts can still be
|
variable is modified by a setter, a copy of the old data structure
|
||||||
accessed.
|
is made and updated, and the pointer to the new data structure is
|
||||||
It is also possible to modify the state in an impure fashion, using
|
returned, such that the old contexts can still be accessed. It is
|
||||||
the =qmckl_context_update_= functions.
|
also possible to modify the state in an impure fashion, using the
|
||||||
The context and its old versions can be destroyed with
|
=qmckl_context_update_= functions. The context and its old
|
||||||
=qmckl_context_destroy=.
|
versions can be destroyed with =qmckl_context_destroy=.
|
||||||
|
|
||||||
*** Low-level functions
|
*** Low-level functions
|
||||||
|
|
||||||
Low-level functions are very simple functions which are leaves of the
|
Low-level functions are very simple functions which are leaves of
|
||||||
function call tree (they don't call any other QMCkl function).
|
the function call tree (they don't call any other QMCkl function).
|
||||||
|
|
||||||
This functions are /pure/, and unaware of the QMCkl =context=. They are
|
These functions are /pure/, and unaware of the QMCkl
|
||||||
not allowed to allocate/deallocate memory, and if they need
|
=context=. They are not allowed to allocate/deallocate memory, and
|
||||||
temporary memory it should be provided in input.
|
if they need temporary memory it should be provided in input.
|
||||||
|
|
||||||
*** High-level functions
|
*** High-level functions
|
||||||
|
|
||||||
High-level functions are at the top of the function call tree.
|
High-level functions are at the top of the function call tree.
|
||||||
They are able to choose which lower-level function to call
|
They are able to choose which lower-level function to call
|
||||||
depending on the required precision, and do the corresponding type
|
depending on the required precision, and do the corresponding type
|
||||||
conversions.
|
conversions. These functions are also responsible for allocating
|
||||||
These functions are also responsible for allocating temporary
|
temporary storage, to simplify the use of accelerators.
|
||||||
storage, to simplify the use of accelerators.
|
|
||||||
|
|
||||||
The high-level functions should be pure, unless the introduction of
|
The high-level functions should be pure, unless the introduction
|
||||||
non-purity is justified. All the side effects should be made in the
|
of non-purity is justified. All the side effects should be made in
|
||||||
=context= variable.
|
the =context= variable.
|
||||||
|
|
||||||
# TODO : We need an identifier for impure functions
|
# TODO : We need an identifier for impure functions
|
||||||
|
|
||||||
*** Numerical precision
|
*** Numerical precision
|
||||||
|
|
||||||
The number of bits of precision required for a function should be
|
The number of bits of precision required for a function should be
|
||||||
given as an input of low-level computational functions. This input will
|
given as an input of low-level computational functions. This input
|
||||||
be used to define the values of the different thresholds that might
|
will be used to define the values of the different thresholds that
|
||||||
be used to avoid computing unnecessary noise.
|
might be used to avoid computing unnecessary noise. High-level
|
||||||
High-level functions will use the precision specified in the
|
functions will use the precision specified in the =context=
|
||||||
=context= variable.
|
variable.
|
||||||
|
|
||||||
** Algorithms
|
** Algorithms
|
||||||
|
|
||||||
Reducing the scaling of an algorithm usually implies also reducing
|
Reducing the scaling of an algorithm usually implies also reducing
|
||||||
its arithmetic complexity (number of flops per byte). Therefore,
|
its arithmetic complexity (number of flops per byte). Therefore,
|
||||||
for small sizes \(\mathcal{O}(N^3)\) and \(\mathcal{O}(N^2)\) algorithms
|
for small sizes \(\mathcal{O}(N^3)\) and \(\mathcal{O}(N^2)\)
|
||||||
are better adapted than linear scaling algorithms.
|
algorithms are better adapted than linear scaling algorithms. As
|
||||||
As QMCkl is a general purpose library, multiple algorithms should
|
QMCkl is a general purpose library, multiple algorithms should be
|
||||||
be implemented adapted to different problem sizes.
|
implemented adapted to different problem sizes.
|
||||||
|
|
||||||
** Rules for the API
|
** Rules for the API
|
||||||
|
|
||||||
@ -206,4 +204,4 @@ rm ${nb}.md
|
|||||||
|
|
||||||
* Documentation
|
* Documentation
|
||||||
|
|
||||||
|
|
||||||
|
106
src/qmckl_ao.org
106
src/qmckl_ao.org
@ -1,7 +1,7 @@
|
|||||||
** Atomic Orbitals
|
** Atomic Orbitals
|
||||||
|
|
||||||
|
|
||||||
This files contains all the routines for the computation of the
|
This files contains all the routines for the computation of the
|
||||||
values, gradients and Laplacian of the atomic basis functions.
|
values, gradients and Laplacian of the atomic basis functions.
|
||||||
|
|
||||||
3 files are produced:
|
3 files are produced:
|
||||||
@ -25,9 +25,12 @@ MunitResult test_qmckl_ao() {
|
|||||||
P_l(\mathbf{r},\mathbf{R}_i) = (x-X_i)^a (y-Y_i)^b (z-Z_i)^c
|
P_l(\mathbf{r},\mathbf{R}_i) = (x-X_i)^a (y-Y_i)^b (z-Z_i)^c
|
||||||
\]
|
\]
|
||||||
\begin{eqnarray*}
|
\begin{eqnarray*}
|
||||||
\frac{\partial }{\partial x} P_l\left(\mathbf{r},\mathbf{R}_i \right) & = & a (x-X_i)^{a-1} (y-Y_i)^b (z-Z_i)^c \\
|
\frac{\partial }{\partial x} P_l\left(\mathbf{r},\mathbf{R}_i \right) &
|
||||||
\frac{\partial }{\partial y} P_l\left(\mathbf{r},\mathbf{R}_i \right) & = & b (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c \\
|
= & a (x-X_i)^{a-1} (y-Y_i)^b (z-Z_i)^c \\
|
||||||
\frac{\partial }{\partial z} P_l\left(\mathbf{r},\mathbf{R}_i \right) & = & c (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} \\
|
\frac{\partial }{\partial y} P_l\left(\mathbf{r},\mathbf{R}_i \right) &
|
||||||
|
= & b (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c \\
|
||||||
|
\frac{\partial }{\partial z} P_l\left(\mathbf{r},\mathbf{R}_i \right) &
|
||||||
|
= & c (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} \\
|
||||||
\end{eqnarray*}
|
\end{eqnarray*}
|
||||||
\begin{eqnarray*}
|
\begin{eqnarray*}
|
||||||
\left( \frac{\partial }{\partial x^2} +
|
\left( \frac{\partial }{\partial x^2} +
|
||||||
@ -39,9 +42,9 @@ MunitResult test_qmckl_ao() {
|
|||||||
&& c(c-1) (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1}
|
&& c(c-1) (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1}
|
||||||
\end{eqnarray*}
|
\end{eqnarray*}
|
||||||
|
|
||||||
**** =qmckl_ao_powers=
|
**** =qmckl_ao_power=
|
||||||
|
|
||||||
Computes all the powers of the =n= input data up to the given
|
Computes all the powers of the =n= input data up to the given
|
||||||
maximum value given in input for each of the $n$ points:
|
maximum value given in input for each of the $n$ points:
|
||||||
|
|
||||||
\[ P_{ij} = X_j^i \]
|
\[ P_{ij} = X_j^i \]
|
||||||
@ -66,7 +69,7 @@ MunitResult test_qmckl_ao() {
|
|||||||
|
|
||||||
***** Header
|
***** Header
|
||||||
#+BEGIN_SRC C :tangle qmckl.h
|
#+BEGIN_SRC C :tangle qmckl.h
|
||||||
qmckl_exit_code qmckl_ao_powers(const qmckl_context context,
|
qmckl_exit_code qmckl_ao_power(const qmckl_context context,
|
||||||
const int64_t n,
|
const int64_t n,
|
||||||
const double *X, const int32_t *LMAX,
|
const double *X, const int32_t *LMAX,
|
||||||
const double *P, const int64_t LDP);
|
const double *P, const int64_t LDP);
|
||||||
@ -74,7 +77,7 @@ qmckl_exit_code qmckl_ao_powers(const qmckl_context context,
|
|||||||
|
|
||||||
***** Source
|
***** Source
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
||||||
integer function qmckl_ao_powers_f(context, n, X, LMAX, P, ldp) result(info)
|
integer function qmckl_ao_power_f(context, n, X, LMAX, P, ldp) result(info)
|
||||||
implicit none
|
implicit none
|
||||||
integer*8 , intent(in) :: context
|
integer*8 , intent(in) :: context
|
||||||
integer*8 , intent(in) :: n
|
integer*8 , intent(in) :: n
|
||||||
@ -104,12 +107,12 @@ integer function qmckl_ao_powers_f(context, n, X, LMAX, P, ldp) result(info)
|
|||||||
end do
|
end do
|
||||||
end do
|
end do
|
||||||
|
|
||||||
end function qmckl_ao_powers_f
|
end function qmckl_ao_power_f
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** C interface :noexport:
|
***** C interface :noexport:
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
||||||
integer(c_int32_t) function qmckl_ao_powers(context, n, X, LMAX, P, ldp) &
|
integer(c_int32_t) function qmckl_ao_power(context, n, X, LMAX, P, ldp) &
|
||||||
bind(C) result(info)
|
bind(C) result(info)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
implicit none
|
implicit none
|
||||||
@ -120,14 +123,14 @@ integer(c_int32_t) function qmckl_ao_powers(context, n, X, LMAX, P, ldp) &
|
|||||||
real (c_double) , intent(out) :: P(ldp,n)
|
real (c_double) , intent(out) :: P(ldp,n)
|
||||||
integer (c_int64_t) , intent(in) , value :: ldp
|
integer (c_int64_t) , intent(in) , value :: ldp
|
||||||
|
|
||||||
integer, external :: qmckl_ao_powers_f
|
integer, external :: qmckl_ao_power_f
|
||||||
info = qmckl_ao_powers_f(context, n, X, LMAX, P, ldp)
|
info = qmckl_ao_power_f(context, n, X, LMAX, P, ldp)
|
||||||
end function qmckl_ao_powers
|
end function qmckl_ao_power
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
interface
|
interface
|
||||||
integer(c_int32_t) function qmckl_ao_powers(context, n, X, LMAX, P, ldp) bind(C)
|
integer(c_int32_t) function qmckl_ao_power(context, n, X, LMAX, P, ldp) bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer (c_int64_t) , intent(in) , value :: context
|
integer (c_int64_t) , intent(in) , value :: context
|
||||||
integer (c_int64_t) , intent(in) , value :: n
|
integer (c_int64_t) , intent(in) , value :: n
|
||||||
@ -135,13 +138,13 @@ end function qmckl_ao_powers
|
|||||||
real (c_double) , intent(in) :: X(n)
|
real (c_double) , intent(in) :: X(n)
|
||||||
integer (c_int32_t) , intent(in) :: LMAX(n)
|
integer (c_int32_t) , intent(in) :: LMAX(n)
|
||||||
real (c_double) , intent(out) :: P(ldp,n)
|
real (c_double) , intent(out) :: P(ldp,n)
|
||||||
end function qmckl_ao_powers
|
end function qmckl_ao_power
|
||||||
end interface
|
end interface
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** Test :noexport:
|
***** Test :noexport:
|
||||||
#+BEGIN_SRC f90 :tangle test_qmckl_ao_f.f90
|
#+BEGIN_SRC f90 :tangle test_qmckl_ao_f.f90
|
||||||
integer(c_int32_t) function test_qmckl_ao_powers(context) bind(C)
|
integer(c_int32_t) function test_qmckl_ao_power(context) bind(C)
|
||||||
use qmckl
|
use qmckl
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@ -165,10 +168,10 @@ integer(c_int32_t) function test_qmckl_ao_powers(context) bind(C)
|
|||||||
LMAX(j) = 1 + int(mod(j, 5),4)
|
LMAX(j) = 1 + int(mod(j, 5),4)
|
||||||
end do
|
end do
|
||||||
|
|
||||||
test_qmckl_ao_powers = qmckl_ao_powers(context, n, X, LMAX, P, LDP)
|
test_qmckl_ao_power = qmckl_ao_power(context, n, X, LMAX, P, LDP)
|
||||||
if (test_qmckl_ao_powers /= 0) return
|
if (test_qmckl_ao_power /= 0) return
|
||||||
|
|
||||||
test_qmckl_ao_powers = -1
|
test_qmckl_ao_power = -1
|
||||||
|
|
||||||
do j=1,n
|
do j=1,n
|
||||||
do i=1,LMAX(j)
|
do i=1,LMAX(j)
|
||||||
@ -180,14 +183,14 @@ integer(c_int32_t) function test_qmckl_ao_powers(context) bind(C)
|
|||||||
end do
|
end do
|
||||||
end do
|
end do
|
||||||
|
|
||||||
test_qmckl_ao_powers = 0
|
test_qmckl_ao_power = 0
|
||||||
deallocate(X,P,LMAX)
|
deallocate(X,P,LMAX)
|
||||||
end function test_qmckl_ao_powers
|
end function test_qmckl_ao_power
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_ao.c
|
#+BEGIN_SRC C :tangle test_qmckl_ao.c
|
||||||
int test_qmckl_ao_powers(qmckl_context context);
|
int test_qmckl_ao_power(qmckl_context context);
|
||||||
munit_assert_int(0, ==, test_qmckl_ao_powers(context));
|
munit_assert_int(0, ==, test_qmckl_ao_power(context));
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +251,7 @@ integer function qmckl_ao_polynomial_vgl_f(context, X, R, lmax, n, L, ldl, VGL,
|
|||||||
real*8 :: Y(3)
|
real*8 :: Y(3)
|
||||||
integer :: lmax_array(3)
|
integer :: lmax_array(3)
|
||||||
real*8 :: pows(-2:lmax,3)
|
real*8 :: pows(-2:lmax,3)
|
||||||
integer, external :: qmckl_ao_powers_f
|
integer, external :: qmckl_ao_power_f
|
||||||
double precision :: xy, yz, xz
|
double precision :: xy, yz, xz
|
||||||
double precision :: da, db, dc, dd
|
double precision :: da, db, dc, dd
|
||||||
|
|
||||||
@ -281,11 +284,11 @@ integer function qmckl_ao_polynomial_vgl_f(context, X, R, lmax, n, L, ldl, VGL,
|
|||||||
pows(-2:-1,1:3) = 0.d0
|
pows(-2:-1,1:3) = 0.d0
|
||||||
pows(0,1:3) = 1.d0
|
pows(0,1:3) = 1.d0
|
||||||
lmax_array(1:3) = lmax
|
lmax_array(1:3) = lmax
|
||||||
info = qmckl_ao_powers_f(context, 1_8, Y(1), (/lmax/), pows(1,1), size(pows,1,kind=8))
|
info = qmckl_ao_power_f(context, 1_8, Y(1), (/lmax/), pows(1,1), size(pows,1,kind=8))
|
||||||
if (info /= 0) return
|
if (info /= 0) return
|
||||||
info = qmckl_ao_powers_f(context, 1_8, Y(2), (/lmax/), pows(1,2), size(pows,1,kind=8))
|
info = qmckl_ao_power_f(context, 1_8, Y(2), (/lmax/), pows(1,2), size(pows,1,kind=8))
|
||||||
if (info /= 0) return
|
if (info /= 0) return
|
||||||
info = qmckl_ao_powers_f(context, 1_8, Y(3), (/lmax/), pows(1,3), size(pows,1,kind=8))
|
info = qmckl_ao_power_f(context, 1_8, Y(3), (/lmax/), pows(1,3), size(pows,1,kind=8))
|
||||||
if (info /= 0) return
|
if (info /= 0) return
|
||||||
|
|
||||||
|
|
||||||
@ -482,7 +485,7 @@ munit_assert_int(0, ==, test_qmckl_ao_polynomial_vgl(context));
|
|||||||
|
|
||||||
*** Gaussian basis functions
|
*** Gaussian basis functions
|
||||||
|
|
||||||
**** =qmckl_ao_gaussians_vgl=
|
**** =qmckl_ao_gaussian_vgl=
|
||||||
|
|
||||||
Computes the values, gradients and Laplacians at a given point of
|
Computes the values, gradients and Laplacians at a given point of
|
||||||
=n= Gaussian functions centered at the same point:
|
=n= Gaussian functions centered at the same point:
|
||||||
@ -516,7 +519,7 @@ munit_assert_int(0, ==, test_qmckl_ao_polynomial_vgl(context));
|
|||||||
|
|
||||||
***** Header
|
***** Header
|
||||||
#+BEGIN_SRC C :tangle qmckl.h
|
#+BEGIN_SRC C :tangle qmckl.h
|
||||||
qmckl_exit_code qmckl_ao_gaussians_vgl(const qmckl_context context,
|
qmckl_exit_code qmckl_ao_gaussian_vgl(const qmckl_context context,
|
||||||
const double *X, const double *R,
|
const double *X, const double *R,
|
||||||
const int64_t *n, const int64_t *A,
|
const int64_t *n, const int64_t *A,
|
||||||
const double *VGL, const int64_t ldv);
|
const double *VGL, const int64_t ldv);
|
||||||
@ -524,7 +527,7 @@ qmckl_exit_code qmckl_ao_gaussians_vgl(const qmckl_context context,
|
|||||||
|
|
||||||
***** Source
|
***** Source
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
||||||
integer function qmckl_ao_gaussians_vgl_f(context, X, R, n, A, VGL, ldv) result(info)
|
integer function qmckl_ao_gaussian_vgl_f(context, X, R, n, A, VGL, ldv) result(info)
|
||||||
implicit none
|
implicit none
|
||||||
integer*8 , intent(in) :: context
|
integer*8 , intent(in) :: context
|
||||||
real*8 , intent(in) :: X(3), R(3)
|
real*8 , intent(in) :: X(3), R(3)
|
||||||
@ -582,12 +585,12 @@ integer function qmckl_ao_gaussians_vgl_f(context, X, R, n, A, VGL, ldv) result(
|
|||||||
VGL(i,5) = (t * A(i) - 6.d0) * VGL(i,5)
|
VGL(i,5) = (t * A(i) - 6.d0) * VGL(i,5)
|
||||||
end do
|
end do
|
||||||
|
|
||||||
end function qmckl_ao_gaussians_vgl_f
|
end function qmckl_ao_gaussian_vgl_f
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** C interface :noexport:
|
***** C interface :noexport:
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
#+BEGIN_SRC f90 :tangle qmckl_ao.f90
|
||||||
integer(c_int32_t) function qmckl_ao_gaussians_vgl(context, X, R, n, A, VGL, ldv) &
|
integer(c_int32_t) function qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) &
|
||||||
bind(C) result(info)
|
bind(C) result(info)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
implicit none
|
implicit none
|
||||||
@ -598,14 +601,14 @@ integer(c_int32_t) function qmckl_ao_gaussians_vgl(context, X, R, n, A, VGL, ldv
|
|||||||
real (c_double) , intent(out) :: VGL(ldv,5)
|
real (c_double) , intent(out) :: VGL(ldv,5)
|
||||||
integer (c_int64_t) , intent(in) , value :: ldv
|
integer (c_int64_t) , intent(in) , value :: ldv
|
||||||
|
|
||||||
integer, external :: qmckl_ao_gaussians_vgl_f
|
integer, external :: qmckl_ao_gaussian_vgl_f
|
||||||
info = qmckl_ao_gaussians_vgl_f(context, X, R, n, A, VGL, ldv)
|
info = qmckl_ao_gaussian_vgl_f(context, X, R, n, A, VGL, ldv)
|
||||||
end function qmckl_ao_gaussians_vgl
|
end function qmckl_ao_gaussian_vgl
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
interface
|
interface
|
||||||
integer(c_int32_t) function qmckl_ao_gaussians_vgl(context, X, R, n, A, VGL, ldv) &
|
integer(c_int32_t) function qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) &
|
||||||
bind(C)
|
bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer (c_int64_t) , intent(in) , value :: context
|
integer (c_int64_t) , intent(in) , value :: context
|
||||||
@ -613,12 +616,12 @@ end function qmckl_ao_gaussians_vgl
|
|||||||
integer (c_int64_t) , intent(in) , value :: n
|
integer (c_int64_t) , intent(in) , value :: n
|
||||||
real (c_double) , intent(in) :: X(3), R(3), A(n)
|
real (c_double) , intent(in) :: X(3), R(3), A(n)
|
||||||
real (c_double) , intent(out) :: VGL(ldv,5)
|
real (c_double) , intent(out) :: VGL(ldv,5)
|
||||||
end function qmckl_ao_gaussians_vgl
|
end function qmckl_ao_gaussian_vgl
|
||||||
end interface
|
end interface
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
***** Test :noexport:
|
***** Test :noexport:
|
||||||
#+BEGIN_SRC f90 :tangle test_qmckl_ao_f.f90
|
#+BEGIN_SRC f90 :tangle test_qmckl_ao_f.f90
|
||||||
integer(c_int32_t) function test_qmckl_ao_gaussians_vgl(context) bind(C)
|
integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C)
|
||||||
use qmckl
|
use qmckl
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@ -645,49 +648,48 @@ integer(c_int32_t) function test_qmckl_ao_gaussians_vgl(context) bind(C)
|
|||||||
end do
|
end do
|
||||||
|
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = &
|
test_qmckl_ao_gaussian_vgl = &
|
||||||
qmckl_ao_gaussians_vgl(context, X, R, n, A, VGL, ldv)
|
qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv)
|
||||||
if (test_qmckl_ao_gaussians_vgl /= 0) return
|
if (test_qmckl_ao_gaussian_vgl /= 0) return
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = -1
|
test_qmckl_ao_gaussian_vgl = -1
|
||||||
|
|
||||||
do i=1,n
|
do i=1,n
|
||||||
test_qmckl_ao_gaussians_vgl = -11
|
test_qmckl_ao_gaussian_vgl = -11
|
||||||
if (dabs(1.d0 - VGL(i,1) / (&
|
if (dabs(1.d0 - VGL(i,1) / (&
|
||||||
dexp(-A(i) * r2) &
|
dexp(-A(i) * r2) &
|
||||||
)) > epsilon ) return
|
)) > epsilon ) return
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = -12
|
test_qmckl_ao_gaussian_vgl = -12
|
||||||
if (dabs(1.d0 - VGL(i,2) / (&
|
if (dabs(1.d0 - VGL(i,2) / (&
|
||||||
-2.d0 * A(i) * Y(1) * dexp(-A(i) * r2) &
|
-2.d0 * A(i) * Y(1) * dexp(-A(i) * r2) &
|
||||||
)) > epsilon ) return
|
)) > epsilon ) return
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = -13
|
test_qmckl_ao_gaussian_vgl = -13
|
||||||
if (dabs(1.d0 - VGL(i,3) / (&
|
if (dabs(1.d0 - VGL(i,3) / (&
|
||||||
-2.d0 * A(i) * Y(2) * dexp(-A(i) * r2) &
|
-2.d0 * A(i) * Y(2) * dexp(-A(i) * r2) &
|
||||||
)) > epsilon ) return
|
)) > epsilon ) return
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = -14
|
test_qmckl_ao_gaussian_vgl = -14
|
||||||
if (dabs(1.d0 - VGL(i,4) / (&
|
if (dabs(1.d0 - VGL(i,4) / (&
|
||||||
-2.d0 * A(i) * Y(3) * dexp(-A(i) * r2) &
|
-2.d0 * A(i) * Y(3) * dexp(-A(i) * r2) &
|
||||||
)) > epsilon ) return
|
)) > epsilon ) return
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = -15
|
test_qmckl_ao_gaussian_vgl = -15
|
||||||
if (dabs(1.d0 - VGL(i,5) / (&
|
if (dabs(1.d0 - VGL(i,5) / (&
|
||||||
A(i) * (4.d0*r2*A(i) - 6.d0) * dexp(-A(i) * r2) &
|
A(i) * (4.d0*r2*A(i) - 6.d0) * dexp(-A(i) * r2) &
|
||||||
)) > epsilon ) return
|
)) > epsilon ) return
|
||||||
end do
|
end do
|
||||||
|
|
||||||
test_qmckl_ao_gaussians_vgl = 0
|
test_qmckl_ao_gaussian_vgl = 0
|
||||||
|
|
||||||
deallocate(VGL)
|
deallocate(VGL)
|
||||||
end function test_qmckl_ao_gaussians_vgl
|
end function test_qmckl_ao_gaussian_vgl
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_ao.c
|
#+BEGIN_SRC C :tangle test_qmckl_ao.c
|
||||||
int test_qmckl_ao_gaussians_vgl(qmckl_context context);
|
int test_qmckl_ao_gaussian_vgl(qmckl_context context);
|
||||||
munit_assert_int(0, ==, test_qmckl_ao_gaussians_vgl(context));
|
munit_assert_int(0, ==, test_qmckl_ao_gaussian_vgl(context));
|
||||||
#+END_SRC
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
** Context
|
** Context
|
||||||
|
|
||||||
This file is written in C because it is more natural to express the context in
|
This file is written in C because it is more natural to express the
|
||||||
C than in Fortran.
|
context in C than in Fortran.
|
||||||
|
|
||||||
2 files are produced:
|
2 files are produced:
|
||||||
- a source file : =qmckl_context.c=
|
- a source file : =qmckl_context.c=
|
||||||
@ -18,46 +18,82 @@
|
|||||||
MunitResult test_qmckl_context() {
|
MunitResult test_qmckl_context() {
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Context
|
*** Context
|
||||||
|
|
||||||
The context variable is a handle for the state of the library, and
|
The context variable is a handle for the state of the library, and
|
||||||
is stored in the following data structure, which can't be seen
|
is stored in the following data structure, which can't be seen
|
||||||
outside of the library. To simplify compatibility with other
|
outside of the library. To simplify compatibility with other
|
||||||
languages, the pointer to the internal data structure is converted
|
languages, the pointer to the internal data structure is converted
|
||||||
into a 64-bit signed integer, defined in the =qmckl_context= type.
|
into a 64-bit signed integer, defined in the =qmckl_context= type.
|
||||||
A value of 0 for the context is equivalent to a =NULL= pointer.
|
A value of 0 for the context is equivalent to a =NULL= pointer.
|
||||||
|
|
||||||
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
# The following code block should be kept to insert comments into
|
||||||
|
# the qmckl.h file
|
||||||
|
|
||||||
|
#+BEGIN_SRC C :comments org :tangle qmckl.h :export none
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** Source
|
**** Basis set data structure
|
||||||
|
|
||||||
The tag is used internally to check if the memory domain pointed by
|
|
||||||
a pointer is a valid context.
|
|
||||||
|
|
||||||
#+BEGIN_SRC C :comments org :tangle qmckl_context.c
|
Data structure for the info related to the atomic orbitals
|
||||||
|
basis set.
|
||||||
|
|
||||||
|
#+BEGIN_SRC C :comments org :tangle qmckl_context.c
|
||||||
|
typedef struct qmckl_ao_basis_struct {
|
||||||
|
|
||||||
|
int64_t shell_num;
|
||||||
|
int64_t prim_num;
|
||||||
|
int64_t * shell_center;
|
||||||
|
int32_t * shell_ang_mom;
|
||||||
|
double * shell_factor;
|
||||||
|
double * exponent ;
|
||||||
|
double * coefficient ;
|
||||||
|
int64_t * shell_prim_num;
|
||||||
|
char type;
|
||||||
|
|
||||||
|
} qmckl_ao_basis_struct;
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
**** Source
|
||||||
|
|
||||||
|
The tag is used internally to check if the memory domain pointed
|
||||||
|
by a pointer is a valid context.
|
||||||
|
|
||||||
|
#+BEGIN_SRC C :comments org :tangle qmckl_context.c
|
||||||
typedef struct qmckl_context_struct {
|
typedef struct qmckl_context_struct {
|
||||||
|
|
||||||
struct qmckl_context_struct * prev;
|
struct qmckl_context_struct * prev;
|
||||||
|
|
||||||
|
/* Molecular system */
|
||||||
|
// struct qmckl_nucleus_struct * nucleus;
|
||||||
|
// struct qmckl_electron_struct * electron;
|
||||||
|
struct qmckl_ao_basis_struct * ao_basis;
|
||||||
|
// struct qmckl_mo_struct * mo;
|
||||||
|
// struct qmckl_determinant_struct * det;
|
||||||
|
|
||||||
|
/* Numerical precision */
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
int32_t precision;
|
int32_t precision;
|
||||||
int32_t range;
|
int32_t range;
|
||||||
|
|
||||||
} qmckl_context_struct;
|
} qmckl_context_struct;
|
||||||
|
|
||||||
#define VALID_TAG 0xBEEFFACE
|
#define VALID_TAG 0xBEEFFACE
|
||||||
#define INVALID_TAG 0xDEADBEEF
|
#define INVALID_TAG 0xDEADBEEF
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** Test :noexport:
|
**** Test :noexport:
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
||||||
qmckl_context context;
|
qmckl_context context;
|
||||||
qmckl_context new_context;
|
qmckl_context new_context;
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
**** =qmckl_context_check=
|
**** =qmckl_context_check=
|
||||||
|
|
||||||
Checks if the domain pointed by the pointer is a valid context.
|
Checks if the domain pointed by the pointer is a valid context.
|
||||||
Returns the input =qmckl_context= if the context is valid, 0 otherwise.
|
Returns the input =qmckl_context= if the context is valid, 0
|
||||||
|
otherwise.
|
||||||
|
|
||||||
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
||||||
qmckl_context qmckl_context_check(const qmckl_context context) ;
|
qmckl_context qmckl_context_check(const qmckl_context context) ;
|
||||||
@ -98,6 +134,7 @@ qmckl_context qmckl_context_create() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context->prev = NULL;
|
context->prev = NULL;
|
||||||
|
context->ao_basis = NULL;
|
||||||
context->precision = QMCKL_DEFAULT_PRECISION;
|
context->precision = QMCKL_DEFAULT_PRECISION;
|
||||||
context->range = QMCKL_DEFAULT_RANGE;
|
context->range = QMCKL_DEFAULT_RANGE;
|
||||||
context->tag = VALID_TAG;
|
context->tag = VALID_TAG;
|
||||||
@ -153,6 +190,7 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_context->prev = old_context;
|
new_context->prev = old_context;
|
||||||
|
new_context->ao_basis = old_context->ao_basis;
|
||||||
new_context->precision = old_context->precision;
|
new_context->precision = old_context->precision;
|
||||||
new_context->range = old_context->range;
|
new_context->range = old_context->range;
|
||||||
new_context->tag = VALID_TAG;
|
new_context->tag = VALID_TAG;
|
||||||
@ -231,9 +269,9 @@ munit_assert_int64(qmckl_context_previous((qmckl_context) 0), ==, (qmckl_context
|
|||||||
- Fails if the 0-valued context is given in argument
|
- Fails if the 0-valued context is given in argument
|
||||||
- Fails if the the pointer is not a valid context
|
- Fails if the the pointer is not a valid context
|
||||||
|
|
||||||
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
||||||
qmckl_exit_code qmckl_context_destroy(qmckl_context context);
|
qmckl_exit_code qmckl_context_destroy(qmckl_context context);
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
***** Source
|
***** Source
|
||||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
@ -271,16 +309,296 @@ munit_assert_int64(qmckl_context_check(new_context), ==, (qmckl_context) 0);
|
|||||||
munit_assert_int64(qmckl_context_destroy((qmckl_context) 0), ==, QMCKL_FAILURE);
|
munit_assert_int64(qmckl_context_destroy((qmckl_context) 0), ==, QMCKL_FAILURE);
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Basis set
|
||||||
|
|
||||||
|
For H_2 with the following basis set,
|
||||||
|
|
||||||
|
#+BEGIN_EXAMPLE
|
||||||
|
HYDROGEN
|
||||||
|
S 5
|
||||||
|
1 3.387000E+01 6.068000E-03
|
||||||
|
2 5.095000E+00 4.530800E-02
|
||||||
|
3 1.159000E+00 2.028220E-01
|
||||||
|
4 3.258000E-01 5.039030E-01
|
||||||
|
5 1.027000E-01 3.834210E-01
|
||||||
|
S 1
|
||||||
|
1 3.258000E-01 1.000000E+00
|
||||||
|
S 1
|
||||||
|
1 1.027000E-01 1.000000E+00
|
||||||
|
P 1
|
||||||
|
1 1.407000E+00 1.000000E+00
|
||||||
|
P 1
|
||||||
|
1 3.880000E-01 1.000000E+00
|
||||||
|
D 1
|
||||||
|
1 1.057000E+00 1.0000000
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
we have:
|
||||||
|
|
||||||
|
#+BEGIN_EXAMPLE
|
||||||
|
type = 'G'
|
||||||
|
shell_num = 12
|
||||||
|
prim_num = 20
|
||||||
|
SHELL_CENTER = [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]
|
||||||
|
SHELL_ANG_MOM = ['S', 'S', 'S', 'P', 'P', 'D', 'S', 'S', 'S', 'P', 'P', 'D']
|
||||||
|
SHELL_PRIM_NUM = [5, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1]
|
||||||
|
prim_index = [1, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20]
|
||||||
|
EXPONENT = [ 33.87, 5.095, 1.159, 0.3258, 0.1027, 0.3258, 0.1027,
|
||||||
|
1.407, 0.388, 1.057, 33.87, 5.095, 1.159, 0.3258, 0.1027,
|
||||||
|
0.3258, 0.1027, 1.407, 0.388, 1.057]
|
||||||
|
COEFFICIENT = [ 0.006068, 0.045308, 0.202822, 0.503903, 0.383421,
|
||||||
|
1.0, 1.0, 1.0, 1.0, 1.0, 0.006068, 0.045308, 0.202822,
|
||||||
|
0.503903, 0.383421, 1.0, 1.0, 1.0, 1.0, 1.0]
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
**** =qmckl_context_update_ao_basis=
|
||||||
|
|
||||||
|
Updates the data describing the AO basis set into the context.
|
||||||
|
|
||||||
|
| =type= | Gaussian or Slater |
|
||||||
|
| =shell_num= | Number of shells |
|
||||||
|
| =prim_num= | Total number of primitives |
|
||||||
|
| =SHELL_CENTER(shell_num)= | Id of the nucleus on which the shell is centered |
|
||||||
|
| =SHELL_ANG_MOM(shell_num)= | Id of the nucleus on which the shell is centered |
|
||||||
|
| =SHELL_FACTOR(shell_num)= | Normalization factor for the shell |
|
||||||
|
| =SHELL_PRIM_NUM(shell_num)= | Number of primitives in the shell |
|
||||||
|
| =SHELL_PRIM_INDEX(shell_num)= | Address of the first primitive of the shelll in the =EXPONENT= array |
|
||||||
|
| =EXPONENT(prim_num)= | Array of exponents |
|
||||||
|
| =COEFFICIENT(prim_num)= | Array of coefficients |
|
||||||
|
|
||||||
|
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
||||||
|
qmckl_exit_code
|
||||||
|
qmckl_context_update_ao_basis(qmckl_context context , const char type,
|
||||||
|
const int64_t shell_num , const int64_t prim_num,
|
||||||
|
const int64_t * SHELL_CENTER, const int32_t * SHELL_ANG_MOM,
|
||||||
|
const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM,
|
||||||
|
const int64_t * SHELL_PRIM_INDEX,
|
||||||
|
const double * EXPONENT , const double * COEFFICIENT);
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** Source
|
||||||
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
|
qmckl_exit_code
|
||||||
|
qmckl_context_update_ao_basis(qmckl_context context , const char type,
|
||||||
|
const int64_t shell_num , const int64_t prim_num,
|
||||||
|
const int64_t * SHELL_CENTER, const int32_t * SHELL_ANG_MOM,
|
||||||
|
const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM,
|
||||||
|
const int64_t * SHELL_PRIM_INDEX,
|
||||||
|
const double * EXPONENT , const double * COEFFICIENT)
|
||||||
|
{
|
||||||
|
|
||||||
|
int64_t i;
|
||||||
|
|
||||||
|
/* Check input */
|
||||||
|
|
||||||
|
if (type != 'G' && type != 'S') return QMCKL_FAILURE;
|
||||||
|
if (shell_num <= 0) return QMCKL_FAILURE;
|
||||||
|
if (prim_num <= 0) return QMCKL_FAILURE;
|
||||||
|
if (prim_num < shell_num) return QMCKL_FAILURE;
|
||||||
|
|
||||||
|
for (i=0 ; i<shell_num ; i++) {
|
||||||
|
if (SHELL_CENTER[i] <= 0) return QMCKL_FAILURE;
|
||||||
|
if (SHELL_PRIM_NUM[i] <= 0) return QMCKL_FAILURE;
|
||||||
|
if (SHELL_ANG_MOM[i] < 0) return QMCKL_FAILURE;
|
||||||
|
if (SHELL_PRIM_INDEX[i] < 0) return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0 ; i<prim_num ; i++) {
|
||||||
|
if (EXPONENT[i] <= 0) return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmckl_context_struct* ctx = (qmckl_context_struct*) context;
|
||||||
|
if (ctx == NULL) return QMCKL_FAILURE;
|
||||||
|
|
||||||
|
qmckl_ao_basis_struct* basis = (qmckl_ao_basis_struct*) malloc (sizeof(qmckl_ao_basis_struct));
|
||||||
|
if (basis == NULL) return QMCKL_FAILURE;
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory allocations */
|
||||||
|
|
||||||
|
basis->shell_center = (int64_t*) malloc (shell_num * sizeof(int64_t));
|
||||||
|
if (basis->shell_center == NULL) {
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
basis->shell_ang_mom = (int32_t*) malloc (shell_num * sizeof(int32_t));
|
||||||
|
if (basis->shell_ang_mom == NULL) {
|
||||||
|
free(basis->shell_center);
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
basis->shell_prim_num= (int64_t*) malloc (shell_num * sizeof(int64_t));
|
||||||
|
if (basis->shell_prim_num == NULL) {
|
||||||
|
free(basis->shell_ang_mom);
|
||||||
|
free(basis->shell_center);
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
basis->shell_factor = (double *) malloc (shell_num * sizeof(double ));
|
||||||
|
if (basis->shell_factor == NULL) {
|
||||||
|
free(basis->shell_prim_num);
|
||||||
|
free(basis->shell_ang_mom);
|
||||||
|
free(basis->shell_center);
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
basis->exponent = (double *) malloc (prim_num * sizeof(double ));
|
||||||
|
if (basis->exponent == NULL) {
|
||||||
|
free(basis->shell_factor);
|
||||||
|
free(basis->shell_prim_num);
|
||||||
|
free(basis->shell_ang_mom);
|
||||||
|
free(basis->shell_center);
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
basis->coefficient = (double *) malloc (prim_num * sizeof(double ));
|
||||||
|
if (basis->coefficient == NULL) {
|
||||||
|
free(basis->exponent);
|
||||||
|
free(basis->shell_factor);
|
||||||
|
free(basis->shell_prim_num);
|
||||||
|
free(basis->shell_ang_mom);
|
||||||
|
free(basis->shell_center);
|
||||||
|
free(basis);
|
||||||
|
return QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Assign data */
|
||||||
|
|
||||||
|
basis->type = type;
|
||||||
|
basis->shell_num = shell_num;
|
||||||
|
basis->prim_num = prim_num;
|
||||||
|
|
||||||
|
for (i=0 ; i<shell_num ; i++) {
|
||||||
|
basis->shell_center [i] = SHELL_CENTER [i];
|
||||||
|
basis->shell_ang_mom [i] = SHELL_ANG_MOM [i];
|
||||||
|
basis->shell_prim_num[i] = SHELL_PRIM_NUM[i];
|
||||||
|
basis->shell_factor [i] = SHELL_FACTOR [i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0 ; i<prim_num ; i++) {
|
||||||
|
basis->exponent [i] = EXPONENT[i];
|
||||||
|
basis->coefficient[i] = COEFFICIENT[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->ao_basis = basis;
|
||||||
|
return QMCKL_SUCCESS;
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** Fortran interface
|
||||||
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
|
interface
|
||||||
|
integer (c_int32_t) function qmckl_context_update_ao_basis(context, &
|
||||||
|
typ, shell_num, prim_num, SHELL_CENTER, SHELL_ANG_MOM, SHELL_FACTOR, &
|
||||||
|
SHELL_PRIM_NUM, SHELL_PRIM_INDEX, EXPONENT, COEFFICIENT) bind(C)
|
||||||
|
use, intrinsic :: iso_c_binding
|
||||||
|
integer (c_int64_t), intent(in), value :: context
|
||||||
|
character(c_char) , intent(in), value :: typ
|
||||||
|
integer (c_int64_t), intent(in), value :: shell_num
|
||||||
|
integer (c_int64_t), intent(in), value :: prim_num
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_CENTER(shell_num)
|
||||||
|
integer (c_int32_t), intent(in) :: SHELL_ANG_MOM(shell_num)
|
||||||
|
double precision , intent(in) :: SHELL_FACTOR(shell_num)
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_PRIM_NUM(shell_num)
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_PRIM_INDEX(shell_num)
|
||||||
|
double precision , intent(in) :: EXPONENT(prim_num)
|
||||||
|
double precision , intent(in) :: COEFFICIENT(prim_num)
|
||||||
|
end function qmckl_context_update_ao_basis
|
||||||
|
end interface
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** TODO Test
|
||||||
|
|
||||||
|
**** =qmckl_context_set_ao_basis=
|
||||||
|
|
||||||
|
Sets the data describing the AO basis set into the context.
|
||||||
|
|
||||||
|
| =type= | Gaussian or Slater |
|
||||||
|
| =shell_num= | Number of shells |
|
||||||
|
| =prim_num= | Total number of primitives |
|
||||||
|
| =SHELL_CENTER(shell_num)= | Id of the nucleus on which the shell is centered |
|
||||||
|
| =SHELL_ANG_MOM(shell_num)= | Id of the nucleus on which the shell is centered |
|
||||||
|
| =SHELL_FACTOR(shell_num)= | Normalization factor for the shell |
|
||||||
|
| =SHELL_PRIM_NUM(shell_num)= | Number of primitives in the shell |
|
||||||
|
| =SHELL_PRIM_INDEX(shell_num)= | Address of the first primitive of the shelll in the =EXPONENT= array |
|
||||||
|
| =EXPONENT(prim_num)= | Array of exponents |
|
||||||
|
| =COEFFICIENT(prim_num)= | Array of coefficients |
|
||||||
|
|
||||||
|
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
||||||
|
qmckl_context
|
||||||
|
qmckl_context_set_ao_basis(const qmckl_context context , const char type,
|
||||||
|
const int64_t shell_num , const int64_t prim_num,
|
||||||
|
const int64_t * SHELL_CENTER, const int32_t * SHELL_ANG_MOM,
|
||||||
|
const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM,
|
||||||
|
const int64_t * SHELL_PRIM_INDEX,
|
||||||
|
const double * EXPONENT , const double * COEFFICIENT);
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** Source
|
||||||
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
|
qmckl_context
|
||||||
|
qmckl_context_set_ao_basis(const qmckl_context context , const char type,
|
||||||
|
const int64_t shell_num , const int64_t prim_num,
|
||||||
|
const int64_t * SHELL_CENTER, const int32_t * SHELL_ANG_MOM,
|
||||||
|
const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM,
|
||||||
|
const int64_t * SHELL_PRIM_INDEX,
|
||||||
|
const double * EXPONENT , const double * COEFFICIENT)
|
||||||
|
{
|
||||||
|
|
||||||
|
qmckl_context new_context = qmckl_context_copy(context);
|
||||||
|
if (new_context == 0) return 0;
|
||||||
|
|
||||||
|
if (qmckl_context_update_ao_basis(context, type, shell_num, prim_num,
|
||||||
|
SHELL_CENTER, SHELL_ANG_MOM, SHELL_FACTOR,
|
||||||
|
SHELL_PRIM_NUM, SHELL_PRIM_INDEX, EXPONENT,
|
||||||
|
COEFFICIENT
|
||||||
|
) == QMCKL_FAILURE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return new_context;
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** Fortran interface
|
||||||
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
|
interface
|
||||||
|
integer (c_int64_t) function qmckl_context_set_ao_basis(context, &
|
||||||
|
typ, shell_num, prim_num, SHELL_CENTER, SHELL_ANG_MOM, SHELL_FACTOR, &
|
||||||
|
SHELL_PRIM_NUM, SHELL_PRIM_INDEX, EXPONENT, COEFFICIENT) bind(C)
|
||||||
|
use, intrinsic :: iso_c_binding
|
||||||
|
integer (c_int64_t), intent(in), value :: context
|
||||||
|
character(c_char) , intent(in), value :: typ
|
||||||
|
integer (c_int64_t), intent(in), value :: shell_num
|
||||||
|
integer (c_int64_t), intent(in), value :: prim_num
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_CENTER(shell_num)
|
||||||
|
integer (c_int32_t), intent(in) :: SHELL_ANG_MOM(shell_num)
|
||||||
|
double precision , intent(in) :: SHELL_FACTOR(shell_num)
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_PRIM_NUM(shell_num)
|
||||||
|
integer (c_int64_t), intent(in) :: SHELL_PRIM_INDEX(shell_num)
|
||||||
|
double precision , intent(in) :: EXPONENT(prim_num)
|
||||||
|
double precision , intent(in) :: COEFFICIENT(prim_num)
|
||||||
|
end function qmckl_context_set_ao_basis
|
||||||
|
end interface
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
***** TODO Test
|
||||||
|
|
||||||
*** Precision
|
*** Precision
|
||||||
|
|
||||||
The following functions set and get the expected required precision
|
The following functions set and get the expected required
|
||||||
and range. =precision= should be an integer between 2 and 53, and
|
precision and range. =precision= should be an integer between 2
|
||||||
=range= should be an integer between 2 and 11.
|
and 53, and =range= should be an integer between 2 and 11.
|
||||||
|
|
||||||
The setter functions functions return a new context as a 64-bit integer.
|
The setter functions functions return a new context as a 64-bit
|
||||||
The getter functions return the value, as a 32-bit integer.
|
integer. The getter functions return the value, as a 32-bit
|
||||||
The update functions return =QMCKL_SUCCESS= or =QMCKL_FAILURE=.
|
integer. The update functions return =QMCKL_SUCCESS= or
|
||||||
|
=QMCKL_FAILURE=.
|
||||||
|
|
||||||
**** =qmckl_context_update_precision=
|
**** =qmckl_context_update_precision=
|
||||||
Modifies the parameter for the numerical precision in a given context.
|
Modifies the parameter for the numerical precision in a given context.
|
||||||
@ -350,7 +668,7 @@ qmckl_exit_code qmckl_context_update_range(const qmckl_context context, const in
|
|||||||
***** TODO Tests :noexport:
|
***** TODO Tests :noexport:
|
||||||
**** =qmckl_context_set_precision=
|
**** =qmckl_context_set_precision=
|
||||||
Returns a copy of the context with a different precision parameter.
|
Returns a copy of the context with a different precision parameter.
|
||||||
#+BEGIN_SRC C :comments or :tangle qmckl.h
|
#+BEGIN_SRC C :comments org :tangle qmckl.h
|
||||||
qmckl_context qmckl_context_set_precision(const qmckl_context context, const int precision);
|
qmckl_context qmckl_context_set_precision(const qmckl_context context, const int precision);
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
@ -369,7 +687,7 @@ qmckl_context qmckl_context_set_precision(const qmckl_context context, const int
|
|||||||
***** Fortran interface
|
***** Fortran interface
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
interface
|
interface
|
||||||
integer (c_int32_t) function qmckl_context_set_precision(context, precision) bind(C)
|
integer (c_int64_t) function qmckl_context_set_precision(context, precision) bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer (c_int64_t), intent(in), value :: context
|
integer (c_int64_t), intent(in), value :: context
|
||||||
integer (c_int32_t), intent(in), value :: precision
|
integer (c_int32_t), intent(in), value :: precision
|
||||||
@ -399,7 +717,7 @@ qmckl_context qmckl_context_set_range(const qmckl_context context, const int ran
|
|||||||
***** Fortran interface
|
***** Fortran interface
|
||||||
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
||||||
interface
|
interface
|
||||||
integer (c_int32_t) function qmckl_context_set_range(context, range) bind(C)
|
integer (c_int64_t) function qmckl_context_set_range(context, range) bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer (c_int64_t), intent(in), value :: context
|
integer (c_int64_t), intent(in), value :: context
|
||||||
integer (c_int32_t), intent(in), value :: range
|
integer (c_int32_t), intent(in), value :: range
|
||||||
@ -486,11 +804,7 @@ double qmckl_context_get_epsilon(const qmckl_context context) {
|
|||||||
|
|
||||||
***** TODO Tests :noexport:
|
***** TODO Tests :noexport:
|
||||||
|
|
||||||
*** Info about the molecular system
|
|
||||||
|
|
||||||
**** TODO =qmckl_context_set_nucl_coord=
|
|
||||||
**** TODO =qmckl_context_set_nucl_charge=
|
|
||||||
**** TODO =qmckl_context_set_elec_num=
|
|
||||||
|
|
||||||
*** End of files :noexport:
|
*** End of files :noexport:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user