mirror of
https://github.com/TREX-CoE/qmckl.git
synced 2025-01-05 11:00:36 +01:00
Fix tests
This commit is contained in:
parent
e00e034497
commit
bd299126c1
224
org/examples.org
224
org/examples.org
@ -3,17 +3,124 @@
|
|||||||
#+INCLUDE: ../tools/lib.org
|
#+INCLUDE: ../tools/lib.org
|
||||||
|
|
||||||
In this section, we present examples of usage of QMCkl.
|
In this section, we present examples of usage of QMCkl.
|
||||||
For simplicity, we assume that the wave function parameters are stores
|
For simplicity, we assume that the wave function parameters are stored
|
||||||
in a [[https://github.com/TREX-CoE/trexio][TREXIO]] file.
|
in a [[https://github.com/TREX-CoE/trexio][TREXIO]] file.
|
||||||
|
|
||||||
* Checking errors
|
* Python
|
||||||
|
|
||||||
All QMCkl functions return an error code. A convenient way to handle
|
** Check numerically that MOs are orthonormal
|
||||||
errors is to write an error-checking function that displays the
|
|
||||||
error in text format and exits the program.
|
|
||||||
|
|
||||||
#+NAME: qmckl_check_error
|
In this example, we will compute the numerically the overlap
|
||||||
#+begin_src f90
|
between the molecular orbitals:
|
||||||
|
|
||||||
|
\[
|
||||||
|
S_{ij} = \int \phi_i(\mathbf{r}) \phi_j(\mathbf{r})
|
||||||
|
\text{d}\mathbf{r} \sim \sum_{k=1}^{N} \phi_i(\mathbf{r}_k)
|
||||||
|
\phi_j(\mathbf{r}_k) \delta \mathbf{r}
|
||||||
|
\]
|
||||||
|
|
||||||
|
|
||||||
|
#+begin_src python :session
|
||||||
|
import numpy as np
|
||||||
|
import qmckl
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
|
||||||
|
|
||||||
|
First, we create a context for the QMCkl calculation, and load the
|
||||||
|
wave function stored in =h2o_5z.h5= inside it:
|
||||||
|
|
||||||
|
#+begin_src python :session
|
||||||
|
trexio_filename = "..//share/qmckl/test_data/h2o_5z.h5"
|
||||||
|
|
||||||
|
context = qmckl.context_create()
|
||||||
|
qmckl.trexio_read(context, trexio_filename)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: None
|
||||||
|
|
||||||
|
We now define the grid points as a regular grid around the
|
||||||
|
molecule.
|
||||||
|
|
||||||
|
We fetch the nuclear coordinates from the context,
|
||||||
|
|
||||||
|
#+begin_src python :session :results output
|
||||||
|
nucl_num = qmckl.get_nucleus_num(context)
|
||||||
|
|
||||||
|
nucl_charge = qmckl.get_nucleus_charge(context, nucl_num)
|
||||||
|
|
||||||
|
nucl_coord = qmckl.get_nucleus_coord(context, 'N', nucl_num*3)
|
||||||
|
nucl_coord = np.reshape(nucl_coord, (3, nucl_num))
|
||||||
|
|
||||||
|
for i in range(nucl_num):
|
||||||
|
print("%d %+f %+f %+f"%(int(nucl_charge[i]),
|
||||||
|
nucl_coord[i,0],
|
||||||
|
nucl_coord[i,1],
|
||||||
|
nucl_coord[i,2]) )
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: 8 +0.000000 +0.000000 +0.000000
|
||||||
|
: 1 -1.430429 +0.000000 -1.107157
|
||||||
|
: 1 +1.430429 +0.000000 -1.107157
|
||||||
|
|
||||||
|
and compute the coordinates of the grid points:
|
||||||
|
|
||||||
|
#+begin_src python :session
|
||||||
|
nx = ( 40, 40, 40 )
|
||||||
|
point_num = nx[0] * nx[1] * nx[2]
|
||||||
|
|
||||||
|
rmin = np.array( list([ np.min(nucl_coord[:,a]) for a in range(3) ]) )
|
||||||
|
rmax = np.array( list([ np.max(nucl_coord[:,a]) for a in range(3) ]) )
|
||||||
|
|
||||||
|
shift = np.array([5.,5.,5.])
|
||||||
|
|
||||||
|
linspace = [ None for i in range(3) ]
|
||||||
|
step = [ None for i in range(3) ]
|
||||||
|
for a in range(3):
|
||||||
|
linspace[a], step[a] = np.linspace(rmin[a]-shift[a],
|
||||||
|
rmax[a]+shift[a],
|
||||||
|
num=nx[a],
|
||||||
|
retstep=True)
|
||||||
|
|
||||||
|
dr = step[0] * step[1] * step[2]
|
||||||
|
dr
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: 0.024081249137090373
|
||||||
|
|
||||||
|
Now the grid is ready, we can create the list of grid points on
|
||||||
|
which the MOs will be evaluated, and transfer them to the QMCkl
|
||||||
|
context:
|
||||||
|
|
||||||
|
#+begin_src python :session
|
||||||
|
point = []
|
||||||
|
for x in linspace[0]:
|
||||||
|
for y in linspace[1]:
|
||||||
|
for z in linspace[2]:
|
||||||
|
point += [x, y, z]
|
||||||
|
|
||||||
|
#point = np.array(point)
|
||||||
|
qmckl.set_point(context, 'N', point, len(point)/3)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
|
||||||
|
Then, will first evaluate all the MOs at the grid points, and then we will
|
||||||
|
compute the overlap between all the MOs.
|
||||||
|
|
||||||
|
* Fortran
|
||||||
|
** Checking errors
|
||||||
|
|
||||||
|
All QMCkl functions return an error code. A convenient way to handle
|
||||||
|
errors is to write an error-checking function that displays the
|
||||||
|
error in text format and exits the program.
|
||||||
|
|
||||||
|
#+NAME: qmckl_check_error
|
||||||
|
#+begin_src f90
|
||||||
subroutine qmckl_check_error(rc, message)
|
subroutine qmckl_check_error(rc, message)
|
||||||
use qmckl
|
use qmckl
|
||||||
implicit none
|
implicit none
|
||||||
@ -27,28 +134,28 @@ subroutine qmckl_check_error(rc, message)
|
|||||||
call exit(rc)
|
call exit(rc)
|
||||||
end if
|
end if
|
||||||
end subroutine qmckl_check_error
|
end subroutine qmckl_check_error
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* Computing an atomic orbital on a grid
|
** Computing an atomic orbital on a grid
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:header-args: :tangle ao_grid.f90
|
:header-args: :tangle ao_grid.f90
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
The following program, in Fortran, computes the values of an atomic
|
The following program, in Fortran, computes the values of an atomic
|
||||||
orbital on a regular 3-dimensional grid. The 100^3 grid points are
|
orbital on a regular 3-dimensional grid. The 100^3 grid points are
|
||||||
automatically defined, such that the molecule fits in a box with 5
|
automatically defined, such that the molecule fits in a box with 5
|
||||||
atomic units in the borders.
|
atomic units in the borders.
|
||||||
|
|
||||||
This program uses the ~qmckl_check_error~ function defined above.
|
This program uses the ~qmckl_check_error~ function defined above.
|
||||||
|
|
||||||
To use this program, run
|
To use this program, run
|
||||||
|
|
||||||
#+begin_src bash :tangle no
|
#+begin_src bash :tangle no
|
||||||
$ ao_grid <trexio_file> <AO_id> <point_num>
|
$ ao_grid <trexio_file> <AO_id> <point_num>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
|
||||||
#+begin_src f90 :noweb yes
|
#+begin_src f90 :noweb yes
|
||||||
<<qmckl_check_error>>
|
<<qmckl_check_error>>
|
||||||
|
|
||||||
program ao_grid
|
program ao_grid
|
||||||
@ -73,11 +180,11 @@ program ao_grid
|
|||||||
double precision :: rmin(3), rmax(3)
|
double precision :: rmin(3), rmax(3)
|
||||||
double precision, allocatable :: points(:,:)
|
double precision, allocatable :: points(:,:)
|
||||||
double precision, allocatable :: ao_vgl(:,:,:)
|
double precision, allocatable :: ao_vgl(:,:,:)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Start by fetching the command-line arguments:
|
Start by fetching the command-line arguments:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
if (iargc() /= 3) then
|
if (iargc() /= 3) then
|
||||||
print *, 'Syntax: ao_grid <trexio_file> <AO_id> <point_num>'
|
print *, 'Syntax: ao_grid <trexio_file> <AO_id> <point_num>'
|
||||||
call exit(-1)
|
call exit(-1)
|
||||||
@ -92,21 +199,21 @@ program ao_grid
|
|||||||
print *, 'Error: 0 < point_num < 300'
|
print *, 'Error: 0 < point_num < 300'
|
||||||
call exit(-1)
|
call exit(-1)
|
||||||
end if
|
end if
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Create the QMCkl context and initialize it with the wave function
|
Create the QMCkl context and initialize it with the wave function
|
||||||
present in the TREXIO file:
|
present in the TREXIO file:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
qmckl_ctx = qmckl_context_create()
|
qmckl_ctx = qmckl_context_create()
|
||||||
rc = qmckl_trexio_read(qmckl_ctx, trexio_filename, 1_8*len(trim(trexio_filename)))
|
rc = qmckl_trexio_read(qmckl_ctx, trexio_filename, 1_8*len(trim(trexio_filename)))
|
||||||
call qmckl_check_error(rc, 'Read TREXIO')
|
call qmckl_check_error(rc, 'Read TREXIO')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We need to check that ~ao_id~ is in the range, so we get the total
|
We need to check that ~ao_id~ is in the range, so we get the total
|
||||||
number of AOs from QMCkl:
|
number of AOs from QMCkl:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
rc = qmckl_get_ao_basis_ao_num(qmckl_ctx, ao_num)
|
rc = qmckl_get_ao_basis_ao_num(qmckl_ctx, ao_num)
|
||||||
call qmckl_check_error(rc, 'Getting ao_num')
|
call qmckl_check_error(rc, 'Getting ao_num')
|
||||||
|
|
||||||
@ -114,24 +221,24 @@ program ao_grid
|
|||||||
print *, 'Error: 0 < ao_id < ', ao_num
|
print *, 'Error: 0 < ao_id < ', ao_num
|
||||||
call exit(-1)
|
call exit(-1)
|
||||||
end if
|
end if
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Now we will compute the limits of the box in which the molecule fits.
|
Now we will compute the limits of the box in which the molecule fits.
|
||||||
For that, we first need to ask QMCkl the coordinates of nuclei.
|
For that, we first need to ask QMCkl the coordinates of nuclei.
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
rc = qmckl_get_nucleus_num(qmckl_ctx, nucl_num)
|
rc = qmckl_get_nucleus_num(qmckl_ctx, nucl_num)
|
||||||
call qmckl_check_error(rc, 'Get nucleus num')
|
call qmckl_check_error(rc, 'Get nucleus num')
|
||||||
|
|
||||||
allocate( nucl_coord(3, nucl_num) )
|
allocate( nucl_coord(3, nucl_num) )
|
||||||
rc = qmckl_get_nucleus_coord(qmckl_ctx, 'N', nucl_coord, 3_8*nucl_num)
|
rc = qmckl_get_nucleus_coord(qmckl_ctx, 'N', nucl_coord, 3_8*nucl_num)
|
||||||
call qmckl_check_error(rc, 'Get nucleus coord')
|
call qmckl_check_error(rc, 'Get nucleus coord')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We now compute the coordinates of opposite points of the box, and
|
We now compute the coordinates of opposite points of the box, and
|
||||||
the distance between points along the 3 directions:
|
the distance between points along the 3 directions:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
rmin(1) = minval( nucl_coord(1,:) ) - 5.d0
|
rmin(1) = minval( nucl_coord(1,:) ) - 5.d0
|
||||||
rmin(2) = minval( nucl_coord(2,:) ) - 5.d0
|
rmin(2) = minval( nucl_coord(2,:) ) - 5.d0
|
||||||
rmin(3) = minval( nucl_coord(3,:) ) - 5.d0
|
rmin(3) = minval( nucl_coord(3,:) ) - 5.d0
|
||||||
@ -141,12 +248,12 @@ program ao_grid
|
|||||||
rmax(3) = maxval( nucl_coord(3,:) ) + 5.d0
|
rmax(3) = maxval( nucl_coord(3,:) ) + 5.d0
|
||||||
|
|
||||||
dr(1:3) = (rmax(1:3) - rmin(1:3)) / dble(point_num_x-1)
|
dr(1:3) = (rmax(1:3) - rmin(1:3)) / dble(point_num_x-1)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We now produce the list of point coordinates where the AO will be
|
We now produce the list of point coordinates where the AO will be
|
||||||
evaluated:
|
evaluated:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
point_num = point_num_x**3
|
point_num = point_num_x**3
|
||||||
allocate( points(point_num, 3) )
|
allocate( points(point_num, 3) )
|
||||||
ipoint=0
|
ipoint=0
|
||||||
@ -166,34 +273,35 @@ program ao_grid
|
|||||||
end do
|
end do
|
||||||
z = z + dr(3)
|
z = z + dr(3)
|
||||||
end do
|
end do
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We give the points to QMCkl:
|
We give the points to QMCkl:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
rc = qmckl_set_point(qmckl_ctx, 'T', points, point_num)
|
rc = qmckl_set_point(qmckl_ctx, 'T', points, point_num)
|
||||||
call qmckl_check_error(rc, 'Setting points')
|
call qmckl_check_error(rc, 'Setting points')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We allocate the space required to retrieve the values, gradients and
|
We allocate the space required to retrieve the values, gradients and
|
||||||
Laplacian of all AOs, and ask to retrieve the values of the
|
Laplacian of all AOs, and ask to retrieve the values of the
|
||||||
AOs computed at the point positions.
|
AOs computed at the point positions.
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
allocate( ao_vgl(ao_num, 5, point_num) )
|
allocate( ao_vgl(ao_num, 5, point_num) )
|
||||||
rc = qmckl_get_ao_basis_ao_vgl(qmckl_ctx, ao_vgl, ao_num*5_8*point_num)
|
rc = qmckl_get_ao_basis_ao_vgl(qmckl_ctx, ao_vgl, ao_num*5_8*point_num)
|
||||||
call qmckl_check_error(rc, 'Setting points')
|
call qmckl_check_error(rc, 'Setting points')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We finally print the value of the AO:
|
We finally print the value of the AO:
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
do ipoint=1, point_num
|
do ipoint=1, point_num
|
||||||
print '(3(F16.10,X),E20.10)', points(ipoint, 1:3), ao_vgl(ao_id,1,ipoint)
|
print '(3(F16.10,X),E20.10)', points(ipoint, 1:3), ao_vgl(ao_id,1,ipoint)
|
||||||
end do
|
end do
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src f90
|
#+begin_src f90
|
||||||
deallocate( nucl_coord, points, ao_vgl )
|
deallocate( nucl_coord, points, ao_vgl )
|
||||||
end program ao_grid
|
end program ao_grid
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -1289,7 +1289,7 @@ end function qmckl_compute_local_energy_f
|
|||||||
|
|
||||||
double local_energy[chbrclf_walk_num];
|
double local_energy[chbrclf_walk_num];
|
||||||
|
|
||||||
rc = qmckl_get_local_energy(context, &(local_energy[0]), walk_num);
|
rc = qmckl_get_local_energy(context, &(local_energy[0]), chbrclf_walk_num);
|
||||||
assert (rc == QMCKL_SUCCESS);
|
assert (rc == QMCKL_SUCCESS);
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
Loading…
Reference in New Issue
Block a user