1!!  gen1int: compute one-electron integrals using rotational London atomic-orbitals
2!!  Copyright 2009-2012 Bin Gao, and Andreas Thorvaldsen
3!!
4!!  gen1int is free software: you can redistribute it and/or modify
5!!  it under the terms of the GNU Lesser General Public License as published by
6!!  the Free Software Foundation, either version 3 of the License, or
7!!  (at your option) any later version.
8!!
9!!  gen1int is distributed in the hope that it will be useful,
10!!  but WITHOUT ANY WARRANTY; without even the implied warranty of
11!!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!!  GNU Lesser General Public License for more details.
13!!
14!!  You should have received a copy of the GNU Lesser General Public License
15!!  along with gen1int. If not, see <http://www.gnu.org/licenses/>.
16!!
17!!  Tests subroutines in nucpot_geom.F90.
18!!
19!!  2011-09-17, Bin Gao
20!!  * first version
21
22  !> \brief tests subroutines in nucpot_geom.F90
23  !> \author Bin Gao
24  !> \date 2011-09-17
25  !> \param io_log is the IO unit of log file
26  !> \return test_failed indicates if the test is failed
27  subroutine test_nucpot_geom(io_log, test_failed)
28    use xkind
29    ! module of HTML test log routines
30    use html_log
31    implicit none
32    integer, intent(in) :: io_log
33    logical, intent(out) :: test_failed
34! parameters of testing primitive integrals
35#include "test_f90/prim_gto.h"
36    integer, parameter :: ORDER_ELEC = 2  !order of electronic derivatives
37    integer orders_geo_pot(2)             !orders of geometric derivatives on nuclear attraction potential origin
38    ! assumes the test will pass
39    test_failed = .false.
40    ! dumps information of tests
41    call html_log_real_array(log_text="Coordinates of bra center:", &
42                             log_real=COORD_BRA, fmt_real="F16.8", io_log=io_log)
43    call html_log_real_number("Orbital exponent of bra center:", &
44                              EXPONENT_BRA, "F16.8", io_log)
45    call html_log_real_array(log_text="Coordinates of ket center:", &
46                             log_real=COORD_KET, fmt_real="F16.8", io_log=io_log)
47    call html_log_real_number("Orbital exponent of ket center:", &
48                              EXPONENT_KET, "F16.8", io_log)
49    call html_log_int_number("Order of electronic derivatives:", &
50                             ORDER_ELEC, "I3", io_log)
51    call html_log_real_array(log_text="Coordinates of nuclear potential origin:", &
52                             log_real=NUCORG, fmt_real="F16.8", io_log=io_log)
53    call html_log_real_number("Scaling constant on operator:", &
54                              SCAL_CONST, "F16.8", io_log)
55    ! the following tests are for individual cases in \fn(nucpot_geom)
56    orders_geo_pot = (/0,0/)
57    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
58    orders_geo_pot = (/0,1/)
59    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
60    orders_geo_pot = (/1,1/)
61    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
62    orders_geo_pot = (/1,7/)
63    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
64    orders_geo_pot = (/1,8/)
65    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
66    orders_geo_pot = (/0,2/)
67    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
68    orders_geo_pot = (/1,2/)
69    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
70    orders_geo_pot = (/2,2/)
71    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
72    orders_geo_pot = (/2,7/)
73    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
74    orders_geo_pot = (/2,8/)
75    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
76    orders_geo_pot = (/3,7/)
77    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
78    orders_geo_pot = (/3,8/)
79    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
80    orders_geo_pot = (/6,15/)
81    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
82    orders_geo_pot = (/6,16/)
83    call sub_test_nucpot_geom(orders_geo_pot, ORDER_ELEC, io_log, test_failed)
84    return
85  end subroutine test_nucpot_geom
86
87  !> \brief tests subroutines in nucpot_geom.F90 with specific orders of geometric derivatives
88  !>        on nuclear attraction potential origin
89  !> \author Bin Gao
90  !> \date 2011-07-27
91  !> \param orders_geo_pot contains the orders of geometric derivatives
92  !> \param order_elec is the order of electronic derivatives
93  !> \param io_log is the IO unit of log file
94  !> \return test_failed indicates if the test is failed
95  subroutine sub_test_nucpot_geom(orders_geo_pot, order_elec, io_log, test_failed)
96    use xkind
97    ! module of HTML test log routines
98    use html_log
99    ! recursive functions of nuclear attraction potential integrals
100    use recur_nucpot
101    implicit none
102    integer, intent(in) :: orders_geo_pot(2)
103    integer, intent(in) :: order_elec
104    integer, intent(in) :: io_log
105    logical, intent(inout) :: test_failed
106! parameters of testing primitive integrals
107#include "test_f90/prim_gto.h"
108    integer dim_geo_pot          !dimension of primitive integrals with zeroth order HGTOs
109    real(REALK), allocatable :: geo_pot_pints(:)
110                                 !primitive integrals with zeroth order HGTOs
111    integer order_geo            !order of geometric derivatives
112    integer x_geo, y_geo, z_geo  !orders of xyz components of geometric derivatives
113    real(REALK) recur_pint       !results from recursive function \fn(recur_nucpot_geom)
114    integer addr_geo             !address of \var(geo_pot_pints)
115    integer ierr                 !error information
116    real(REALK) begin_time       !begin of CPU time
117    real(REALK) end_time         !end of CPU time
118    logical different            !if result from \fn(nucpot_geom) is different from reference
119    ! dumps information of tests
120    call html_log_int_array(                                                       &
121           log_text="Orders of geometric derivative on nuclear potential origin:", &
122           log_int=orders_geo_pot, fmt_int="I3", io_log=io_log, separation="&rarr;")
123    ! gets the begin time
124    call xtimer_set(begin_time)
125    ! allocates memory for the integrals from \fn(nucpot_geom)
126    if (orders_geo_pot(1)>0) then
127      dim_geo_pot = ((orders_geo_pot(2)+1)*(orders_geo_pot(2)+2)*(orders_geo_pot(2)+3) &
128                  -  orders_geo_pot(1)*(orders_geo_pot(1)+1)*(orders_geo_pot(1)+2))/6
129    else
130      dim_geo_pot = (orders_geo_pot(2)+1)*(orders_geo_pot(2)+2)*(orders_geo_pot(2)+3)/6
131    end if
132    allocate(geo_pot_pints(dim_geo_pot), stat=ierr)
133    if (ierr/=0) then
134      call html_log_int_number(log_text="Failed to allocate geo_pot_pints:", &
135                               log_int=dim_geo_pot, fmt_int="I12",           &
136                               io_log=io_log, font_color="red")
137      test_failed = .true.
138      return
139    end if
140    ! calculates the integrals using \fn(nucpot_geom)
141    call nucpot_geom(COORD_BRA, EXPONENT_BRA, COORD_KET, EXPONENT_KET, &
142                      NUCORG, SCAL_CONST, orders_geo_pot, order_elec,  &
143                      dim_geo_pot, geo_pot_pints)
144    ! gets the end time
145    call xtimer_set(end_time)
146    ! prints the CPU elapsed time
147    call html_log_real_number(log_text="Time (s) used for nucpot_geom:",      &
148                              log_real=end_time-begin_time, fmt_real="F10.4", &
149                              io_log=io_log, font_color="blue")
150    ! resets the begin time
151    call xtimer_set(begin_time)
152    ! sets the data used for the module \fn(recur_nucpot)
153    call recur_nucpot_create(coord_bra=COORD_BRA, exponent_bra=EXPONENT_BRA, &
154                             coord_ket=COORD_KET, exponent_ket=EXPONENT_KET, &
155                             nucpot_origin=NUCORG, dipole_origin=DIPORG,     &
156                             scal_const=SCAL_CONST, order_elec=order_elec,   &
157                             order_aux=orders_geo_pot(2))
158    ! initializes the address of integrals from \fn(nucpot_geom)
159    addr_geo = 0
160    ! loops over the orders of geometric derivatives
161    do order_geo = orders_geo_pot(1), orders_geo_pot(2)
162      ! loops over xyz components
163      do z_geo = 0, order_geo
164        do y_geo = 0, order_geo-z_geo
165          x_geo = order_geo-(z_geo+y_geo)
166          ! integral from \fn(recur_nucpot_geom)
167          recur_pint = recur_nucpot_geom((/x_geo,y_geo,z_geo/), 0)
168          addr_geo = addr_geo+1
169          call check_difference(recur_pint, geo_pot_pints(addr_geo), &
170                                different)
171          if (different) then
172            call html_log_int_array(                               &
173                   log_text="Orders of geometric derivative on "// &
174                            "nuclear potential origin:",           &
175                   log_int=(/x_geo,y_geo,z_geo/), fmt_int="I3",    &
176                   io_log=io_log)
177            call html_log_real_number(                           &
178                   log_text="Reference from recur_nucpot_geom:", &
179                   log_real=recur_pint, fmt_real="Es20.12",      &
180                   io_log=io_log, font_color="blue")
181            call html_log_real_number(log_text="Result from nucpot_geom:", &
182                                      log_real=geo_pot_pints(addr_geo),    &
183                                      fmt_real="Es20.12", io_log=io_log,   &
184                                      font_color="red")
185            test_failed = .true.
186          end if
187        end do
188      end do
189    end do
190    call recur_nucpot_destroy
191    ! gets the end time
192    call xtimer_set(end_time)
193    ! prints the CPU elapsed time
194    call html_log_real_number(log_text="Time (s) used for recur_nucpot_geom:", &
195                              log_real=end_time-begin_time, fmt_real="F10.4",  &
196                              io_log=io_log, font_color="blue")
197    ! cleans
198    deallocate(geo_pot_pints)
199    return
200  end subroutine sub_test_nucpot_geom
201