Commit 05750e15 authored by Yingzhou Li's avatar Yingzhou Li

Reorganized files to match the master branch structure

parents
Yingzhou Li, Duke University, USA
* Email: yingzhou.li {at} duke {dot} edu
* Homepage: <http://www.yingzhouli.com/>
Jianfeng Lu, Duke University, USA
* Email: jianfeng {at} math {dot} duke {dot} edu
* Homepage: <https://math.duke.edu/~jianfeng/>
### ELSI_RCI source files ###
LIST(APPEND elsi_rci_src
src/elsi_rci_constants.f90
src/elsi_rci_datatype.f90
src/elsi_rci_ops.f90
src/elsi_rci_precision.f90
src/elsi_rci_setup.f90
src/Davidson/elsi_rci_davidson.f90
src/OMM/elsi_rci_omm.f90
src/OMM/rci_omm_quartic.f90)
ADD_LIBRARY(elsi_rci ${elsi_rci_src})
TARGET_LINK_LIBRARIES(elsi_rci PRIVATE ${LIBS})
TARGET_INCLUDE_DIRECTORIES(elsi_rci PRIVATE ${INC_PATHS})
INSTALL(TARGETS elsi_rci
EXPORT elsiConfig
DESTINATION ${CMAKE_INSTALL_LIBDIR})
This diff is collapsed.
This diff is collapsed.
! Copied from libOMM (author: Fabiano Corsetti)
! License BSD-3
!================================================!
! calculate the coeffs. of the quartic line !
! search equation from three energy points and !
! two gradient points !
!================================================!
subroutine rci_omm_fit_quartic(x, y, g, c)
use ELSI_RCI_PRECISION, only:r8
implicit none
!**** INPUT ***********************************!
real(r8), intent(in) :: x(1:3) ! three x-points {x_i}
real(r8), intent(in) :: y(1:3) ! y(x_i) at the three points
real(r8), intent(in) :: g(1:2) ! (dy/dx)|x_i at the first two points
!**** OUTPUT **********************************!
real(r8), intent(out) :: c(0:4) ! coeffs. of the quartic equation
!**********************************************!
! The following expressions for the coeffs. were produced
! automatically using Maple 12
c(4) = (x(3)**3*x(2)*g(1) - 3*x(1)*x(2)**2*y(1) + 3*y(3)*x(1)*x(2)**2 &
+ x(1)**2*x(2)**2*g(1) + x(3)*x(2)**3* &
g(1) + 2*x(1)**2*x(3)**2*g(2) - 3*x(2)*x(3)**2*y(1) &
+ 3*y(2)*x(1)**2*x(2) - x(3)**3*x(1)*g(1) + x(3)**3* &
x(2)*g(2) - x(2)**2*x(3)**2*g(2) - x(1)**2*x(2)**2*g(2) &
- 2*x(2)**2*x(3)**2*g(1) + 3*x(2)*x(3)**2* &
y(2) + x(1)**2*x(3)**2*g(1) - x(1)*x(2)**3*g(1) &
- 3*x(1)*x(3)**2*y(1) - x(3)**3*x(1)*g(2) + 3*x(1)* &
x(3)**2*y(2) + x(2)*g(2)*x(1)**3 - 3*y(3)*x(1)**2*x(2) &
- x(3)*g(2)*x(1)**3 + 6*x(1)*x(3)*x(2)*y(1) + 2* &
x(1)*x(3)*x(2)**2*g(2) + x(1)*x(3)**2*x(2)*g(1) &
- x(1)*x(3)**2*x(2)*g(2) - 2*x(1)**2*x(3)*x(2)*g(1) - &
x(1)**2*x(3)*x(2)*g(2) + x(1)*x(3)*x(2)**2*g(1) &
- 6*x(1)*x(3)*x(2)*y(2) + 2*x(3)**3*y(1) - 2*x(3)**3* &
y(2) + x(2)**3*y(1) + y(3)*x(1)**3 - y(3)*x(2)**3 &
- y(2)*x(1)**3) &
/(-2*x(3)**3*x(1)**4 + x(3)**4*x(1)**3 - &
x(1)**2*x(2)**5 - x(3)**4*x(2)**3 - x(2)**5*x(3)**2 &
- 3*x(1)**4*x(2)**3 + 2*x(3)**3*x(2)**4 + x(1)**5* &
x(3)**2 + 3*x(2)**4*x(1)**3 + 4*x(3)**3*x(2)*x(1)**3 &
- 4*x(3)**3*x(1)*x(2)**3 + 2*x(1)*x(3)*x(2)**5 + 4* &
x(1)**4*x(3)*x(2)**2 + 8*x(1)**2*x(3)**2*x(2)**3 &
+ x(1)**4*x(3)**2*x(2) - x(1)*x(3)**2*x(2)**4 - 2* &
x(1)**5*x(3)*x(2) - 4*x(1)**2*x(3)*x(2)**4 &
+ x(1)**5*x(2)**2 - 8*x(2)**2*x(3)**2*x(1)**3 - 3*x(3)**4* &
x(1)**2*x(2) + 3*x(3)**4*x(1)*x(2)**2)
c(3) = -(-x(1)*g(1) + 2*c(4)*x(1)**4 - x(1)*g(2) &
+ 4*x(1)*c(4)*x(2)**3 + x(2)*g(1) - 4*x(2)*c(4)*x(1)**3 &
+ x(2)*g(2) - 2*c(4)*x(2)**4 + 2*y(1) - 2*y(2)) &
/(x(1)**3 + 3*x(1)*x(2)**2 - 3*x(2)*x(1)**2 - x(2)**3)
c(2) = -(-y(2) + c(4)*x(2)**4 + c(3)*x(2)**3 + x(2)*g(1) &
- 4*x(2)*c(4)*x(1)**3 - 3*x(2)*c(3)*x(1)**2 + y(1) &
+ 3*c(4)*x(1)**4 + 2*c(3)*x(1)**3 - x(1)*g(1)) &
/(x(1)**2 - 2*x(1)*x(2) + x(2)**2)
c(1) = g(1) - 4*c(4)*x(1)**3 - 3*c(3)*x(1)**2 - 2*c(2)*x(1)
c(0) = y(1) - c(4)*x(1)**4 - c(3)*x(1)**3 - c(2)*x(1)**2 - c(1)*x(1)
end subroutine rci_omm_fit_quartic
!================================================!
! find the minimum for the quartic line search !
! equation !
!================================================!
subroutine rci_omm_solve_quartic(c, x_min, fail)
use ELSI_RCI_PRECISION, only:r8
implicit none
!**** INPUT ***********************************!
real(r8), intent(in) :: c(0:4) ! coeffs. of the quartic equation
!**** OUTPUT **********************************!
logical, intent(out) :: fail ! did we fail to find a minimum?
real(r8), intent(out) :: x_min ! position of minimum
!**** LOCAL ***********************************!
integer :: x_order(1:3)
real(r8) :: Pi = 3.141592653589793238462643383279502884197_r8
real(r8) :: t(1:3)
real(r8) :: z(1:3)
real(r8) :: a
real(r8) :: b
real(r8) :: d
real(r8) :: Q
real(r8) :: R
real(r8) :: theta
real(r8) :: S
real(r8) :: U
!**********************************************!
fail = .false.
! In order to find the minimum of the quartic equation,
! we have to solve a cubic equation; the following method
! is taken from Numerical Recipes
a = 3.0_r8*c(3)/(4.0_r8*c(4))
b = 2.0_r8*c(2)/(4.0_r8*c(4))
if ((abs(b) >= 1.0d11) .or. (abs(c(4)) <= 1.0d-11)) then
x_min = -0.5_r8*c(1)/c(2)
return
end if
d = c(1)/(4.0_r8*c(4))
Q = (a**2 - 3.0_r8*b)/9.0_r8
R = (2.0_r8*a**3 - 9.0_r8*a*b + 27.0_r8*d)/54.0_r8
if (R**2 < Q**3) then
theta = acos(R/sqrt(Q**3))
t(1) = -2.0_r8*sqrt(Q)*cos(theta/3.0_r8) - a/3.0_r8
t(2) = -2.0_r8*sqrt(Q)*cos((theta + 2.0_r8*Pi)/3.0_r8) - a/3.0_r8
t(3) = -2.0_r8*sqrt(Q)*cos((theta - 2.0_r8*Pi)/3.0_r8) - a/3.0_r8
z(1:3) = c(4)*t(1:3)**4 + c(3)*t(1:3)**3 + c(2)*t(1:3)**2 &
+ c(1)*t(1:3) + c(0)
if (c(4) > 0.0_r8) then
if (all(z(1) >= z(2:3))) then
x_order(1:3) = (/1, 2, 3/)
else if (z(2) > z(3)) then
x_order(1:3) = (/2, 3, 1/)
else
x_order(1:3) = (/3, 1, 2/)
end if
if ((0.0_r8 <= t(x_order(1))) &
.and. (t(x_order(2)) <= t(x_order(1)))) then
x_min = t(x_order(2))
else
x_min = t(x_order(3))
end if
else
if (all(z(1) <= z(2:3))) then
x_min = t(1)
else if (z(2) < z(3)) then
x_min = t(2)
else
x_min = t(3)
end if
end if
else
S = -sign(1.0_r8, R)*(abs(R) + sqrt(R**2 - Q**3))**(1.0_r8/3.0_r8)
if (S == 0.0_r8) then
U = 0.0_r8
else
U = Q/S
end if
x_min = (S + U) - (a/3.0_r8)
if (c(4) < 0.0_r8) fail = .true.
end if
end subroutine rci_omm_solve_quartic
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module contains constants used in ELSI RCI.
!!
module ELSI_RCI_CONSTANTS
use ELSI_RCI_PRECISION, only:i4
implicit none
!&<
! Constant of solver
integer(i4), parameter :: RCI_SOLVER = -1
integer(i4), parameter :: RCI_SOLVER_DAVIDSON = 1
integer(i4), parameter :: RCI_SOLVER_OMM = 2
! Constant of ijob
integer(i4), parameter :: RCI_INIT_IJOB = -1
! Constant of task
integer(i4), parameter :: RCI_NULL = 0
integer(i4), parameter :: RCI_CONVERGE = 1
integer(i4), parameter :: RCI_ALLOCATE = 2
integer(i4), parameter :: RCI_DEALLOCATE = 3
integer(i4), parameter :: RCI_STOP = 4
integer(i4), parameter :: RCI_H_MULTI = 5
integer(i4), parameter :: RCI_S_MULTI = 6
integer(i4), parameter :: RCI_P_MULTI = 7
integer(i4), parameter :: RCI_GEMM = 8
integer(i4), parameter :: RCI_AXPY = 9
integer(i4), parameter :: RCI_COPY = 10
integer(i4), parameter :: RCI_SUBCOPY = 11
integer(i4), parameter :: RCI_TRACE = 12
integer(i4), parameter :: RCI_DOT = 13
integer(i4), parameter :: RCI_SCALE = 14
integer(i4), parameter :: RCI_COLSCALE = 15
integer(i4), parameter :: RCI_ROWSCALE = 16
integer(i4), parameter :: RCI_HEGV = 17
integer(i4), parameter :: RCI_COL_NORM = 18
integer(i4), parameter :: RCI_SUBCOL = 19
!&>
end module ELSI_RCI_CONSTANTS
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module contains variables accessible in ELSI RCI and related modules.
!!
module ELSI_RCI_DATATYPE
use, intrinsic :: ISO_C_BINDING
use ELSI_RCI_PRECISION
use ELSI_RCI_CONSTANTS
implicit none
! RCI Instruction type
! H: Hamiltonian; S: Overlapping matrix; P: Preconditioner
! A, B, C: General matrices
type, public :: rci_instr
character :: jobz, uplo ! job char; and upper or lower
character :: trH, trS, trP, trA, trB ! Operation for H, S, P, A, B
integer :: m, n ! size of the output matrix
integer :: k ! size of the intermedia multiplication
integer :: lda, ldb, ldc ! leading size for matrix A, B and C
integer :: rAoff,cAoff ! row and column offset of A
integer :: rBoff,cBoff ! row and column offset of B
integer :: Aidx, Bidx, Cidx ! indices for matrix A, B and C
real(r8) :: alpha, beta ! coefficients
end type
type, public :: rci_handle
integer(i4) :: solver = RCI_SOLVER
! Output
logical :: print_mem = .false.
! Overlap
logical :: ovlp_is_unit = .false.
! Iteration
integer(i4) :: max_iter
integer(i4) :: n_res ! size of resvec
real(r8) :: tol_iter
! Result
integer(i4) :: total_iter
real(r8) :: total_energy
! Physics
integer(i4) :: n_basis
integer(i4) :: n_state
! Davidson
integer(i4) :: davidson_max_n
end type
end module ELSI_RCI_DATATYPE
This diff is collapsed.
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module provides choices of precisions.
!!
module ELSI_RCI_PRECISION
use, intrinsic :: ISO_C_BINDING, only:c_float, c_double, &
c_int32_t, c_int64_t
implicit none
integer, parameter :: r4 = c_float
integer, parameter :: r8 = c_double
integer, parameter :: i4 = c_int32_t
integer, parameter :: i8 = c_int64_t
end module ELSI_RCI_PRECISION
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module contains operations used within RCI.
!!
module ELSI_RCI_SETUP
use ELSI_RCI_DATATYPE
use ELSI_RCI_PRECISION, only:r8, i4
implicit none
contains
subroutine rci_init(r_h, solver, n_basis, n_state, tol_iter, max_iter)
implicit none
type(rci_handle), intent(out) :: r_h !< Handle
integer(i4), intent(in) :: solver !< Refer to RCI_CONSTANTS
integer(i4), intent(in) :: n_basis !< Number of basis
integer(i4), intent(in) :: n_state !< Number of states
real(r8), intent(in) :: tol_iter !< Number of basis
integer(i4), intent(in) :: max_iter !< Number of states
r_h%solver = solver
r_h%n_basis = n_basis
r_h%n_state = n_state
r_h%tol_iter = tol_iter
r_h%max_iter = max_iter
r_h%total_energy = 0.0_r8
r_h%total_iter = 0
select case (solver)
case (RCI_SOLVER_DAVIDSON)
r_h%n_res = min(2*n_state,n_basis)
case (RCI_SOLVER_OMM)
r_h%n_res = n_state
end select
! Davidson default
r_h%davidson_max_n = min(2*n_state,n_basis)
end subroutine
end module ELSI_RCI_SETUP
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment