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 trace_ints.F90.
18!!
19!!  2011-08-04, Bin Gao
20!!  * first version
21
22  !> \brief tests subroutines in trace_ints.F90
23  !> \author Bin Gao
24  !> \date 2011-08-04
25  !> \param io_log is the IO unit of log file
26  !> \return test_failed indicates if the test is failed
27  subroutine test_trace_ints(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    integer, parameter :: ANG_BRA = 10                    !angular number on bra center
35    integer, parameter :: ANG_KET = 12                    !angular number on ket center
36    integer, parameter :: NUM_SGTO_BRA = 2*ANG_BRA+1      !number of SGTOs on bra center
37    integer, parameter :: NUM_SGTO_KET = 2*ANG_KET+1      !number of SGTOs on ket center
38    integer mag_bra(NUM_SGTO_BRA)                         !magnetic numbers on bra center
39    integer mag_ket(NUM_SGTO_KET)                         !magnetic numbers on ket center
40    integer, parameter :: NUM_CONTR_BRA = 10              !number of contractions on bra center
41    integer, parameter :: NUM_CONTR_KET = 12              !number of contractions on ket center
42    integer, parameter :: NUM_OPT = 6                     !number of operators
43    real(REALK) sgto_ints(NUM_SGTO_BRA,NUM_CONTR_BRA, &   !contracted SGTO integrals from Gen1Int
44                          NUM_SGTO_KET,NUM_CONTR_KET,NUM_OPT)
45    real(REALK) ro_sints(NUM_SGTO_BRA,NUM_CONTR_BRA, &    !reordered SGTO integrals
46                         NUM_SGTO_KET,NUM_CONTR_KET,NUM_OPT)
47    real(REALK) dens_sints(NUM_SGTO_KET,NUM_CONTR_KET, &  !atomic-orbital density matrix using SGTOs
48                           NUM_SGTO_BRA,NUM_CONTR_BRA,NUM_OPT)
49    integer, parameter :: NUM_CGTO_BRA = (ANG_BRA+1)*(ANG_BRA+2)/2  !number of CGTOs on bra center
50    integer, parameter :: NUM_CGTO_KET = (ANG_KET+1)*(ANG_KET+2)/2  !number of CGTOs on ket center
51    integer power_bra(3,NUM_CGTO_BRA)                               !Cartesian powers on bra center
52    integer power_ket(3,NUM_CGTO_KET)                               !Cartesian powers on ket center
53    real(REALK) cgto_ints(NUM_CGTO_BRA,NUM_CONTR_BRA, &   !contracted CGTO integrals from Gen1Int
54                          NUM_CGTO_KET,NUM_CONTR_KET,NUM_OPT)
55    real(REALK) ro_cints(NUM_CGTO_BRA,NUM_CONTR_BRA, &    !reordered CGTO integrals
56                         NUM_CGTO_KET,NUM_CONTR_KET,NUM_OPT)
57    real(REALK) dens_cints(NUM_CGTO_KET,NUM_CONTR_KET, &  !atomic-orbital density matrix using CGTOs
58                           NUM_CGTO_BRA,NUM_CONTR_BRA,NUM_OPT)
59    real(REALK) tr_ints(NUM_OPT)                          !traces of integrals
60    real(REALK) ref_tr(NUM_OPT)                           !referenced traces of integrals
61    integer ibra, iket, icontr, jcontr, iopt              !incremental recorders
62    integer ypow, zpow                                    !incremental recorders over yz powers
63    integer addr_bra, addr_ket                            !addresses of GTOs on bra and ket centers
64    real(REALK) begin_time                                !begin of CPU time
65    real(REALK) end_time                                  !end of CPU time
66    logical different                                     !if result is different from reference
67    ! we first test subroutines in reorder_ints.F90 which will be used later on
68    call html_log_text("We first test subroutines in reorder_ints.F90 ...", io_log)
69    call test_reorder_ints(io_log, test_failed)
70    if (test_failed) then
71      call html_log_text(log_text="Tests subroutines in reorder_ints.F90 failed! "// &
72                                  "No further test will be performed!",              &
73                         io_log=io_log, font_color="red")
74      return
75    else
76      call html_log_text("Tests subroutines in reorder_ints.F90 passed!", io_log)
77    end if
78    ! sets SGTOs on bra and centers, which are in the reverse order of Gen1Int
79    do ibra = 1, NUM_SGTO_BRA
80      mag_bra(ibra) = ANG_BRA-ibra+1
81    end do
82    do iket = 1, NUM_SGTO_KET
83      mag_ket(iket) = ANG_KET-iket+1
84    end do
85    ! sets the integrals
86    do iopt = 1, NUM_OPT
87      do jcontr = 1, NUM_CONTR_KET
88        do iket = 1, NUM_SGTO_KET
89          do icontr = 1, NUM_CONTR_BRA
90            do ibra = 1, NUM_SGTO_BRA
91              sgto_ints(ibra,icontr,iket,jcontr,iopt)                            &
92                = real(ibra,REALK)*0.01_REALK+real(icontr,REALK)*0.001_REALK     &
93                + real(iket,REALK)*0.0001_REALK+real(jcontr,REALK)*0.00001_REALK &
94                + real(iopt,REALK)*0.000001_REALK
95            end do
96          end do
97        end do
98      end do
99    end do
100    ! sets the atomic-orbital density matrix
101    do iopt = 1, NUM_OPT
102      do icontr = 1, NUM_CONTR_BRA
103        do ibra = 1, NUM_SGTO_BRA
104          do jcontr = 1, NUM_CONTR_KET
105            do iket = 1, NUM_SGTO_KET
106              dens_sints(iket,jcontr,ibra,icontr,iopt)                           &
107                = real(ibra,REALK)*0.01_REALK+real(icontr,REALK)*0.001_REALK     &
108                + real(iket,REALK)*0.0001_REALK+real(jcontr,REALK)*0.00001_REALK &
109                + real(iopt,REALK)*0.000001_REALK
110            end do
111          end do
112        end do
113      end do
114    end do
115    ! reorders the SGTOs on bra and ket centers using \fn(reorder_sgto_ints)
116    call reorder_sgto_ints(ANG_BRA, NUM_SGTO_BRA, mag_bra, &
117                           ANG_KET, NUM_SGTO_KET, mag_ket, &
118                           NUM_CONTR_BRA, NUM_CONTR_KET,   &
119                           NUM_OPT, sgto_ints, ro_sints)
120    ! gets the traces from \fn(trace_gto_ints) as referenced results
121    ref_tr = 0.0_REALK
122    call trace_gto_ints(NUM_SGTO_BRA, NUM_CONTR_BRA, NUM_SGTO_KET, NUM_CONTR_KET, &
123                        NUM_OPT, ro_sints, dens_sints, ref_tr)
124    ! dumps information of tests
125    call html_log_heading(heading="Tests subroutine trace_sgto_ints", &
126                          io_log=io_log, level=4)
127    ! gets the begin time
128    call xtimer_set(begin_time)
129    ! gets the traces using \fn(trace_sgto_ints)
130    tr_ints = 0.0_REALK
131    call trace_sgto_ints(ANG_BRA, NUM_SGTO_BRA, mag_bra, &
132                         ANG_KET, NUM_SGTO_KET, mag_ket, &
133                         NUM_CONTR_BRA, NUM_CONTR_KET,   &
134                         NUM_OPT, sgto_ints, dens_sints, tr_ints)
135    ! gets the end time
136    call xtimer_set(end_time)
137    ! prints the CPU elapsed time
138    call html_log_real_number(log_text="Time (s) used for trace_sgto_ints:",  &
139                              log_real=end_time-begin_time, fmt_real="F10.4", &
140                              io_log=io_log, font_color="blue")
141    ! checks the results
142    do iopt = 1, NUM_OPT
143      call check_difference(ref_tr(iopt), tr_ints(iopt), different)
144      if (different) then
145        call html_log_int_number("ID of operator:", iopt, "I3", io_log)
146        call html_log_real_number(log_text="Referenced result:",           &
147                                  log_real=ref_tr(iopt), fmt_real="F16.6", &
148                                  io_log=io_log, font_color="blue")
149        call html_log_real_number(log_text="Result from trace_sgto_ints:",  &
150                                  log_real=tr_ints(iopt), fmt_real="F16.6", &
151                                  io_log=io_log, font_color="red")
152        test_failed = .true.
153      end if
154    end do
155    ! sets CGTOs on bra and centers, which are in the reverse order of Gen1Int
156    addr_bra = 0
157    do zpow = ANG_BRA, 0, -1
158      do ypow = ANG_BRA-zpow, 0, -1
159        addr_bra = addr_bra+1
160        power_bra(1,addr_bra) = ANG_BRA-(zpow+ypow)
161        power_bra(2,addr_bra) = ypow
162        power_bra(3,addr_bra) = zpow
163      end do
164    end do
165    addr_ket = 0
166    do zpow = ANG_KET, 0, -1
167      do ypow = ANG_KET-zpow, 0, -1
168        addr_ket = addr_ket+1
169        power_ket(1,addr_ket) = ANG_KET-(zpow+ypow)
170        power_ket(2,addr_ket) = ypow
171        power_ket(3,addr_ket) = zpow
172      end do
173    end do
174    ! sets the integrals
175    do iopt = 1, NUM_OPT
176      do jcontr = 1, NUM_CONTR_KET
177        do iket = 1, NUM_CGTO_KET
178          do icontr = 1, NUM_CONTR_BRA
179            do ibra = 1, NUM_CGTO_BRA
180              cgto_ints(ibra,icontr,iket,jcontr,iopt)                            &
181                = real(ibra,REALK)*0.01_REALK+real(icontr,REALK)*0.001_REALK     &
182                + real(iket,REALK)*0.0001_REALK+real(jcontr,REALK)*0.00001_REALK &
183                + real(iopt,REALK)*0.000001_REALK
184            end do
185          end do
186        end do
187      end do
188    end do
189    ! sets the atomic-orbital density matrix
190    do iopt = 1, NUM_OPT
191      do icontr = 1, NUM_CONTR_BRA
192        do ibra = 1, NUM_CGTO_BRA
193          do jcontr = 1, NUM_CONTR_KET
194            do iket = 1, NUM_CGTO_KET
195              dens_cints(iket,jcontr,ibra,icontr,iopt)                           &
196                = real(ibra,REALK)*0.01_REALK+real(icontr,REALK)*0.001_REALK     &
197                + real(iket,REALK)*0.0001_REALK+real(jcontr,REALK)*0.00001_REALK &
198                + real(iopt,REALK)*0.000001_REALK
199            end do
200          end do
201        end do
202      end do
203    end do
204    ! reorders the CGTOs on bra and ket centers using \fn(reorder_cgto_ints)
205    call reorder_cgto_ints(ANG_BRA, NUM_CGTO_BRA, power_bra, &
206                           ANG_KET, NUM_CGTO_KET, power_ket, &
207                           NUM_CONTR_BRA, NUM_CONTR_KET,     &
208                           NUM_OPT, cgto_ints, ro_cints)
209    ! gets the traces from \fn(trace_gto_ints) as referenced results
210    ref_tr = 0.0_REALK
211    call trace_gto_ints(NUM_CGTO_BRA, NUM_CONTR_BRA, NUM_CGTO_KET, NUM_CONTR_KET, &
212                        NUM_OPT, ro_cints, dens_cints, ref_tr)
213    ! dumps information of tests
214    call html_log_heading(heading="Tests subroutine trace_cgto_ints", &
215                          io_log=io_log, level=4)
216    ! resets the begin time
217    call xtimer_set(begin_time)
218    ! gets the traces using \fn(trace_cgto_ints)
219    tr_ints = 0.0_REALK
220    call trace_cgto_ints(ANG_BRA, NUM_CGTO_BRA, power_bra, &
221                         ANG_KET, NUM_CGTO_KET, power_ket, &
222                         NUM_CONTR_BRA, NUM_CONTR_KET,     &
223                         NUM_OPT, cgto_ints, dens_cints, tr_ints)
224    ! gets the end time
225    call xtimer_set(end_time)
226    ! prints the CPU elapsed time
227    call html_log_real_number(log_text="Time (s) used for trace_cgto_ints:",  &
228                              log_real=end_time-begin_time, fmt_real="F10.4", &
229                              io_log=io_log, font_color="blue")
230    ! checks the results
231    do iopt = 1, NUM_OPT
232      call check_difference(ref_tr(iopt), tr_ints(iopt), different)
233      if (different) then
234        call html_log_int_number("ID of operator:", iopt, "I3", io_log)
235        call html_log_real_number(log_text="Referenced result:",           &
236                                  log_real=ref_tr(iopt), fmt_real="F16.6", &
237                                  io_log=io_log, font_color="blue")
238        call html_log_real_number(log_text="Result from trace_cgto_ints:",  &
239                                  log_real=tr_ints(iopt), fmt_real="F16.6", &
240                                  io_log=io_log, font_color="red")
241        test_failed = .true.
242      end if
243    end do
244    return
245  end subroutine test_trace_ints
246