mirror of https://github.com/QMCPACK/qmcpack.git
Initial revision
git-svn-id: https://subversion.assembla.com/svn/qmcdev/trunk@4 e5b18d87-469d-4833-9cc0-8cdfa06e9491
This commit is contained in:
parent
47ef55c27a
commit
cb7d66f5af
|
@ -0,0 +1,80 @@
|
|||
#
|
||||
#adding compiler flags
|
||||
#
|
||||
#Since F77FLAGS is used with ADD_CUSTOM_COMMAND variable F77FLAGS needs to be comma separated.
|
||||
# incorrect: SET(F77OPTFLAGS "-fpp2 -O3 -unrol -fno-alias -ftz")
|
||||
# correct: SET(F77OPTFLAGS -fpp2 -O3 -unrol -fno-alias -ftz)
|
||||
|
||||
MESSAGE(STATUS "Configuring compiler flags")
|
||||
|
||||
IF($ENV{CXX} MATCHES icc)
|
||||
SET(INTEL_COMPILER 1)
|
||||
ADD_DEFINITIONS(-DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-restrict -unroll -fno-alias -O3 -xW")
|
||||
# SET(FORTRAN_LIBS "-lPEPCF90 -lCEPCF90 -lF90 -lintrins")
|
||||
SET(FORTRAN_LIBS "-lifcore")
|
||||
SET(F77 ifc)
|
||||
SET(F77OPTFLAGS -fpp2 -O3)
|
||||
SET(F77FLAGS ${F77OPTFLAGS})
|
||||
ENDIF($ENV{CXX} MATCHES icc)
|
||||
|
||||
IF($ENV{CXX} MATCHES ecc)
|
||||
SET(INTEL_COMPILER 1)
|
||||
ADD_DEFINITIONS(-DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-restrict -unroll -fno-alias -O3 -ftz")
|
||||
SET(FORTRAN_LIBS "-lPEPCF90 -lCEPCF90 -lF90 -lintrins")
|
||||
SET(F77 efc)
|
||||
SET(F77OPTFLAGS -fpp2 -O3 -unrol -fno-alias -ftz)
|
||||
SET(F77FLAGS ${F77OPTFLAGS})
|
||||
ENDIF($ENV{CXX} MATCHES ecc)
|
||||
|
||||
IF(INTEL_COMPILER)
|
||||
MESSAGE(STATUS "Using intel compiler")
|
||||
IF(OHMMS_OMP)
|
||||
ADD_DEFINITIONS(-DUSE_OPENMP)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -openmp")
|
||||
SET(ENABLE_OMP 1 CACHE BOOL "OpenMP is enabled")
|
||||
ENDIF(OHMMS_OMP)
|
||||
ENDIF(INTEL_COMPILER)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
|
||||
# set the customized compiler flags
|
||||
SET(CMAKE_CXX_FLAGS "-O3 -qstrict -qarch=auto -qtune=auto -qansialias -qkeepinlines -qinline=1000 -qspill=2000 -qalias=typeptr -qnoeh -qnothreaded -qrtti=dyna")
|
||||
|
||||
# set the fortran libraries for linker
|
||||
SET(FORTRAN_LIBS " -lxlf90 -lxlf")
|
||||
|
||||
# check if the compiler is correct xlC_r xlc_r mpCC_r mpcc_r
|
||||
IF(OHMMS_OMP)
|
||||
IF($ENV{CXX} MATCHES "_r")
|
||||
ADD_DEFINITIONS(-DUSE_OPENMP)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -qsmp=omp")
|
||||
SET(F77 xlf_r)
|
||||
SET(ENABLE_OMP 1 CACHE BOOL "OpenMP is enabled")
|
||||
ELSE($ENV{CXX} MATCHES "_r")
|
||||
MESSAGE(STATUS "OpenMP is not enabled. Change CXX to xlC_r/mpCC_r")
|
||||
SET(F77 xlf)
|
||||
ENDIF($ENV{CXX} MATCHES "_r")
|
||||
ELSE(OHMMS_OMP)
|
||||
SET(F77 xlf)
|
||||
ENDIF(OHMMS_OMP)
|
||||
|
||||
SET(F77OPTFLAGS -O3 -qstrict -qarch=auto -qtune=auto)
|
||||
SET(F77FLAGS ${F77OPTFLAGS})
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
|
||||
IF(NOT INTEL_COMPILER)
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-Drestrict=__restrict__ -DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-O3 -ftemplate-depth-60 -Drestrict=__restrict__ -fstrict-aliasing -funroll-all-loops -finline-limit=1000 -ffast-math -Wno-deprecated")
|
||||
# SET(CMAKE_CXX_FLAGS "-g")
|
||||
SET(FORTRAN_LIBS "-lg2c")
|
||||
SET(F77 g77)
|
||||
SET(F77FLAGS -funroll-loops -O3)
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ENDIF(NOT INTEL_COMPILER)
|
||||
|
||||
IF(APPLE)
|
||||
INCLUDE_DIRECTORIES(/sw/include)
|
||||
ENDIF(APPLE)
|
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# this module look for blitz++ (http://www.oonumerics.org/blitz) support
|
||||
# it will define the following values
|
||||
#
|
||||
# BLITZ_INCLUDE_DIR = where blitz/blitz.h can be found
|
||||
#
|
||||
# May want to define this but seldom required
|
||||
# BLITZ_LIBRARY = where blitz library can be found (reserved)
|
||||
#
|
||||
IF(EXISTS ${PROJECT_CMAKE}/BlitzppConfig.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/BlitzppConfig.cmake)
|
||||
ENDIF(EXISTS ${PROJECT_CMAKE}/BlitzppConfig.cmake)
|
||||
|
||||
IF(Blitzpp_INCLUDE_DIRS)
|
||||
FIND_PATH(BLITZ_INCLUDE_DIR blitz/blitz.h ${Blitzpp_INCLUDE_DIRS})
|
||||
ELSE(Blitzpp_INCLUDE_DIRS)
|
||||
FIND_PATH(BLITZ_INCLUDE_DIR blitz/blitz.h
|
||||
/usr/apps/include
|
||||
/usr/include
|
||||
/opt/include
|
||||
/usr/local/include
|
||||
)
|
||||
ENDIF(Blitzpp_INCLUDE_DIRS)
|
||||
|
||||
IF(BLITZ_INCLUDE_IDR)
|
||||
SET(FOUND_BLITZ 1 CACHE BOOL "Found blitz++ library")
|
||||
ELSE(BLITZ_INCLUDE_IDR)
|
||||
SET(FOUND_BLITZ 0 CACHE BOOL "Found blitz++ library")
|
||||
ENDIF(BLITZ_INCLUDE_IDR)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
BLITZ_INCLUDE_DIR
|
||||
FOUND_BLITZ
|
||||
)
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# this module look for gsl (http://www.gnu.org/software/gsl) support
|
||||
# it will define the following values
|
||||
#
|
||||
# GSL_INCLUDE_DIR = where gsl/gsl_version.h can be found
|
||||
# GSL_LIBRARY = the library to link against libgsl
|
||||
# FOUND_GSL = set to 1 if gsl is found
|
||||
#
|
||||
|
||||
IF(EXISTS ${PROJECT_CMAKE}/GslConfig.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/GslConfig.cmake)
|
||||
ENDIF(EXISTS ${PROJECT_CMAKE}/GslConfig.cmake)
|
||||
|
||||
IF(Gsl_INCLUDE_DIRS)
|
||||
|
||||
FIND_PATH(GSL_INCLUDE_DIR gsl/gsl_version.h ${Gsl_INCLUDE_DIRS})
|
||||
FIND_LIBRARY(GSL_LIBRARY gsl ${Gsl_LIBRARY_DIRS})
|
||||
|
||||
ELSE(Gsl_INCLUDE_DIRS)
|
||||
|
||||
SET(TRIAL_LIBRARY_PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
SET(TRIAL_INCLUDE_PATHS
|
||||
/usr/include
|
||||
/opt/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(GSL_LIBRARY gsl ${TRIAL_LIBRARY_PATHS})
|
||||
FIND_PATH(GSL_INCLUDE_DIR gsl/gsl_version.h ${TRIAL_INCLUDE_PATHS} )
|
||||
|
||||
ENDIF(Gsl_INCLUDE_DIRS)
|
||||
|
||||
IF(GSL_INCLUDE_DIR AND GSL_LIBRARY)
|
||||
SET(FOUND_GSL 1 CACHE BOOL "Found gsl library")
|
||||
SET(GSL_LIBRARY ${GSL_LIBRARY} -lgslcblas)
|
||||
ELSE(GSL_INCLUDE_DIR AND GSL_LIBRARY)
|
||||
SET(FOUND_GSL 0 CACHE BOOL "Not fount gsl library")
|
||||
ENDIF(GSL_INCLUDE_DIR AND GSL_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
GSL_INCLUDE_DIR
|
||||
GSL_LIBRARY
|
||||
FOUND_GSL
|
||||
)
|
|
@ -0,0 +1,62 @@
|
|||
#
|
||||
# this module look for HDF5 (http://hdf.ncsa.uiuc.edu) support
|
||||
# it will define the following values
|
||||
#
|
||||
# HDF5_INCLUDE_DIR = where hdf5.h can be found
|
||||
# HDF5_LIBRARY = the library to link against (hdf5 etc)
|
||||
# FOUND_HDF5 = set to true after finding the library
|
||||
#
|
||||
IF(EXISTS ${PROJECT_CMAKE}/Hdf5Config.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/Hdf5Config.cmake)
|
||||
ENDIF(EXISTS ${PROJECT_CMAKE}/Hdf5Config.cmake)
|
||||
|
||||
IF(Hdf5_INCLUDE_DIRS)
|
||||
|
||||
FIND_PATH(HDF5_INCLUDE_DIR hdf5.h ${Hdf5_INCLUDE_DIRS})
|
||||
FIND_LIBRARY(HDF5_LIBRARY hdf5 ${Hdf5_LIBRARY_DIRS})
|
||||
|
||||
ELSE(Hdf5_INCLUDE_DIRS)
|
||||
|
||||
SET(TRIAL_LIBRARY_PATHS
|
||||
/usr/apps/lib
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
SET(TRIAL_INCLUDE_PATHS
|
||||
/usr/apps/include
|
||||
/usr/include
|
||||
/opt/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(TRIAL_LIBRARY_PATHS /usr/apps/hdf5/gcc3/lib ${TRIAL_LIBRARY_PATHS} )
|
||||
SET(TRIAL_INCLUDE_PATHS /usr/apps/hdf5/gcc3/include ${TRIAL_INCLUDE_PATHS} )
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
IF($ENV{HDF5_DIR} MATCHES "hdf")
|
||||
MESSAGE(STATUS "Using environment variable HDF5_DIR.")
|
||||
SET(TRIAL_LIBRARY_PATHS $ENV{HDF5_DIR}/lib ${TRIAL_LIBRARY_PATHS} )
|
||||
SET(TRIAL_INCLUDE_PATHS $ENV{HDF5_DIR}/include ${TRIAL_INCLUDE_PATHS} )
|
||||
ENDIF($ENV{HDF5_DIR} MATCHES "hdf")
|
||||
|
||||
FIND_LIBRARY(HDF5_LIBRARY hdf5 ${TRIAL_LIBRARY_PATHS})
|
||||
FIND_PATH(HDF5_INCLUDE_DIR hdf5.h ${TRIAL_INCLUDE_PATHS} )
|
||||
|
||||
ENDIF(Hdf5_INCLUDE_DIRS)
|
||||
|
||||
IF(HDF5_INCLUDE_DIR AND HDF5_LIBRARY)
|
||||
SET(FOUND_HDF5 1 CACHE BOOL "Found hdf5 library")
|
||||
ELSE(HDF5_INCLUDE_DIR AND HDF5_LIBRARY)
|
||||
SET(FOUND_HDF5 0 CACHE BOOL "Not fount hdf5 library")
|
||||
ENDIF(HDF5_INCLUDE_DIR AND HDF5_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
HDF5_INCLUDE_DIR
|
||||
HDF5_LIBRARY
|
||||
FOUND_HDF5
|
||||
)
|
|
@ -0,0 +1,136 @@
|
|||
# this module look for lapack/blas and other numerical library support
|
||||
# it will define the following values
|
||||
# LAPACK_LIBRARY
|
||||
# BLAS_LIBRARY
|
||||
#
|
||||
# 1) search ENV MKL
|
||||
# 2) search MKL in usual paths
|
||||
# 3) search ENV ATLAS
|
||||
# 4) search lapack/blas
|
||||
# 5) give up
|
||||
#
|
||||
SET(MKL_PATHS "")
|
||||
|
||||
#use environment variables
|
||||
IF(INTEL_COMPILER)
|
||||
#use environment variables: e.g, module at OSC uses MKL
|
||||
IF($ENV{MKL} MATCHES "mkl")
|
||||
|
||||
MESSAGE(STATUS "Using intel/mkl library: $ENV{MKL}")
|
||||
|
||||
#look for the path where the mkl is installed
|
||||
STRING(REGEX MATCHALL "[-][L]([^ ;])+" MKL_PATH_WITH_PREFIX "$ENV{MKL}")
|
||||
STRING(REGEX REPLACE "[-][L]" "" MKL_PATHS ${MKL_PATH_WITH_PREFIX})
|
||||
|
||||
ENDIF($ENV{MKL} MATCHES "mkl")
|
||||
|
||||
SET(MKL_PATHS ${MKL_PATHS}
|
||||
/usr/local/intel/mkl60/mkl60/lib/64
|
||||
/usr/local/intel/mkl/lib/32
|
||||
/opt/intel/mkl/lib/32
|
||||
)
|
||||
MESSAGE(STATUS "Looking for intel/mkl library in ${MKL_PATHS}")
|
||||
|
||||
# IF($ENV{MKL}) MATCHES "mkl")
|
||||
# MESSAGE(STATUS "Using intel/mkl library: $ENV{MKL}")
|
||||
# SET(LAPACK_LIBRARY $ENV{MKL})
|
||||
# SET(BLAS_LIBRARY " ")
|
||||
# SET(LAPACK_LIBRARY_INIT 1)
|
||||
# ENDIF($ENV{MKL}) MATCHES "mkl")
|
||||
|
||||
IF(NOT LAPACK_LIBRARY_INIT)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY
|
||||
NAMES mkl_lapack
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
FIND_LIBRARY(BLAS_LIBRARY
|
||||
NAMES mkl mkl_itp
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
FIND_LIBRARY(BLAS_EXTRA_LIBRARY
|
||||
NAMES guide
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
IF(LAPACK_LIBRARY MATCHES "mkl")
|
||||
MESSAGE(STATUS "Found intel/mkl library")
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
SET(BLAS_LIBRARY_INIT 1 CACHE BOOL "blas is initialized")
|
||||
ENDIF(LAPACK_LIBRARY MATCHES "mkl")
|
||||
ENDIF(NOT LAPACK_LIBRARY_INIT)
|
||||
ENDIF(INTEL_COMPILER)
|
||||
|
||||
IF($ENV{ATLAS} MATCHES "atlas")
|
||||
IF($ENV{ATLAS} MATCHES "lapack")
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized with ATLAS env")
|
||||
ENDIF($ENV{ATLAS} MATCHES "lapack")
|
||||
SET(BLAS_LIBRARY $ENV{ATLAS})
|
||||
SET(BLAS_LIBRARY_INIT 1 CACHE BOOL "blas is initialized with ATLAS env")
|
||||
ENDIF($ENV{ATLAS} MATCHES "atlas")
|
||||
|
||||
IF($ENV{LAPACK} MATCHES "lapack")
|
||||
SET(LAPACK_LIBRARY $ENV{LAPACK})
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
ENDIF($ENV{LAPACK} MATCHES "lapack")
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
SET(ELIB essl)
|
||||
IF(ENABLE_OMP)
|
||||
SET(ELIB esslsmp)
|
||||
ENDIF(ENABLE_OMP)
|
||||
|
||||
IF(NOT LAPACK_LIBRARY_INIT)
|
||||
SET(LLIB lapack-SP4_32 lapack)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY
|
||||
NAMES ${LLIB}
|
||||
PATHS /usr/apps/math/lapack/LAPACK
|
||||
lib
|
||||
)
|
||||
FIND_LIBRARY(BLAS_LIBRARY ${ELIB}
|
||||
/usr/lib
|
||||
)
|
||||
ENDIF(NOT LAPACK_LIBRARY_INIT)
|
||||
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
SET(BLAS_LIBRARY_INIT 1 CACHE BOOL "blas with essl is initialized")
|
||||
MESSAGE(STATUS "Found lapack/blas on AIX system")
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
|
||||
IF(NOT LAPACK_LIBRARY_INIT)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY NAMES lapack lapack_gnu
|
||||
PATHS /usr/apps/math/lapack
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
IF(LAPACK_LIBRARY)
|
||||
MESSAGE(STATUS "Found netlib lapack library")
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
ENDIF(LAPACK_LIBRARY)
|
||||
ENDIF(NOT LAPACK_LIBRARY_INIT)
|
||||
|
||||
IF(NOT BLAS_LIBRARY_INIT)
|
||||
FIND_LIBRARY(BLAS_LIBRARY NAMES blas blas_gnu
|
||||
PATHS /usr/apps/math/lapack
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
IF(BLAS_LIBRARY)
|
||||
MESSAGE(STATUS "Found netlib blas is found")
|
||||
SET(BLAS_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
ENDIF(BLAS_LIBRARY)
|
||||
ENDIF(NOT BLAS_LIBRARY_INIT)
|
||||
|
||||
### BRANDT
|
||||
### MOVED BECAUSE OF SCOPE PROBLEM
|
||||
### PROBABLY SHOULD BE FIXED
|
||||
#SET(BLAS_LIBRARY ${BLAS_LIBRARY} ${BLAS_EXTRA_LIBRARY})
|
||||
#SET(BLAS_EXTRA_LIBRARY ${BLAS_EXTRA_LIBRARY} ${ATLAS_LIBS})
|
||||
|
||||
SET(BLAS_LIBRARY ${BLAS_LIBRARY})
|
||||
MARK_AS_ADVANCED(
|
||||
LAPACK_LIBRARY
|
||||
BLAS_LIBRARY
|
||||
)
|
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# this module look for libxml (http://www.xmlsoft.org) support
|
||||
# it will define the following values
|
||||
#
|
||||
# LIBXML2_INCLUDE_DIR = where libxml/xpath.h can be found
|
||||
# LIBXML2_LIBRARY = the library to link against libxml2
|
||||
# FOUND_LIBXML2 = set to 1 if libxml2 is found
|
||||
#
|
||||
IF(EXISTS ${PROJECT_CMAKE}/Libxml2Config.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/Libxml2Config.cmake)
|
||||
ENDIF(EXISTS ${PROJECT_CMAKE}/Libxml2Config.cmake)
|
||||
|
||||
IF(Libxml2_INCLUDE_DIRS)
|
||||
|
||||
FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h ${Libxml2_INCLUDE_DIRS})
|
||||
FIND_LIBRARY(LIBXML2_LIBRARY xml2 ${Libxml2_LIBRARY_DIRS})
|
||||
|
||||
ELSE(Libxml2_INCLUDE_DIRS)
|
||||
|
||||
FIND_LIBRARY(LIBXML2_LIBRARY xml2
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h
|
||||
/usr/include/libxml2
|
||||
/usr/local/include/libxml2
|
||||
/sw/include/libxml2
|
||||
)
|
||||
ENDIF(Libxml2_INCLUDE_DIRS)
|
||||
|
||||
IF(LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARY)
|
||||
SET(FOUND_LIBXML2 1 CACHE BOOL "Found libxml2 library")
|
||||
ELSE(LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARY)
|
||||
SET(FOUND_LIBXML2 0 CACHE BOOL "Not fount libxml2 library")
|
||||
ENDIF(LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
LIBXML2_INCLUDE_DIR
|
||||
LIBXML2_LIBRARY
|
||||
FOUND_LIBXML2
|
||||
)
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# this module look for libxml++ (http://libxmlplusplus.sourceforge.net) support
|
||||
# it will define the following values
|
||||
#
|
||||
# LIBXMLPP_INCLUDE_PATH = where libxml++/libxml++.h can be found
|
||||
# LIBXMLPP_LIBRARY = the library to link against libxml++
|
||||
# FOUND_LIBXMLPP = set to 1 if libxml++ is found
|
||||
#
|
||||
SET(LIBXMLPP xml++-1.0)
|
||||
IF(EXISTS ${PROJECT_CMAKE}/LibxmlppConfig.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/LibxmlppConfig.cmake)
|
||||
ENDIF(EXISTS ${PROJECT_CMAKE}/LibxmlppConfig.cmake)
|
||||
|
||||
IF(Libxmlpp_INCLUDE_DIRS)
|
||||
|
||||
FIND_PATH(LIBXMLPP_INCLUDE_DIR libxml++/libxml++.h ${Libxmlpp_INCLUDE_DIRS})
|
||||
FIND_LIBRARY(LIBXMLPP_LIBRARY ${LIBXMLPP} ${Libxmlpp_LIBRARY_DIRS})
|
||||
|
||||
ELSE(Libxmlpp_INCLUDE_DIRS)
|
||||
|
||||
FIND_LIBRARY(LIBXMLPP_LIBRARY
|
||||
${LIBXMLPP}
|
||||
/usr/app/lib
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
FIND_PATH(LIBXMLPP_INCLUDE_DIR
|
||||
libxml++/libxml++.h
|
||||
/usr/app/include/libxml++-1.0
|
||||
/usr/include/libxml++-1.0
|
||||
/usr/local/include/libxml++-1.0
|
||||
/sw/include/libxml++-1.0
|
||||
)
|
||||
ENDIF(Libxmlpp_INCLUDE_DIRS)
|
||||
|
||||
IF(LIBXMLPP_INCLUDE_DIR AND LIBXMLPP_LIBRARY)
|
||||
SET(FOUND_LIBXMLPP 1 CACHE BOOL "Found libxml++ library")
|
||||
ELSE(LIBXMLPP_INCLUDE_DIR AND LIBXMLPP_LIBRARY)
|
||||
SET(FOUND_LIBXMLPP 0 CACHE BOOL "Not fount libxml2 library")
|
||||
ENDIF(LIBXMLPP_INCLUDE_DIR AND LIBXMLPP_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
LIBXMLPP_INCLUDE_DIR
|
||||
LIBXMLPP_LIBRARY
|
||||
FOUND_LIBXMLPP
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
#GNU compilers
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-Drestrict=__restrict__ -DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-O6 -ftemplate-depth-60 -Drestrict=__restrict__ -fstrict-aliasing -funroll-all-loops -finline-limit=1000 -ffast-math -Wno-deprecated")
|
||||
# SET(CMAKE_CXX_FLAGS "-g -ftemplate-depth-60 -Drestrict=__restrict__ -fstrict-aliasing -Wno-deprecated")
|
||||
SET(FORTRAN_LIBS "-lg2c")
|
||||
SET(F77 g77)
|
||||
SET(F77FLAGS -funroll-loops -O3)
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
IF(APPLE)
|
||||
INCLUDE_DIRECTORIES(/sw/include)
|
||||
ENDIF(APPLE)
|
|
@ -0,0 +1,18 @@
|
|||
IF(APPLE)
|
||||
INCLUDE_DIRECTORIES(/sw/include)
|
||||
ENDIF(APPLE)
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-Drestrict=__restrict__ -DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-ftemplate-depth-60 -Drestrict=__restrict__ -O3 -fstrict-aliasing -funroll-all-loops -finline-limit=1000 -ffast-math -Wno-deprecated")
|
||||
SET (FORTRAN_LIBS "-lg2c")
|
||||
SET(F77 g77)
|
||||
SET(F77OPTFLAGS "-O3 -funroll-loops")
|
||||
SET(F77FLAGS ${F77OPTFLAGS})
|
||||
ELSE(CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-DADD_)
|
||||
SET(CMAKE_CXX_FLAGS "-restrict -unroll")
|
||||
SET(FORTRAN_LIBS "-lPEPCF90 -lCEPCF90 -lF90 -lintrins")
|
||||
SET(F77 ifc)
|
||||
SET(F77OPTFLAGS "-fpp2 -O3")
|
||||
SET(F77FLAGS ${F77OPTFLAGS})
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
IF(UNIX)
|
||||
IF(RUN_CONFIGURE)
|
||||
EXEC_PROGRAM(
|
||||
"${ABINITDIR}/configure --prefix=${PROJECT_BINARY_DIR}" ${ABINITDIR}
|
||||
)
|
||||
EXEC_PROGRAM(make ${ABINITDIR})
|
||||
EXEC_PROGRAM(make ${ABINITDIR} ARGS install)
|
||||
FIND_LIBRARY(ABINIT_LIBRARY abinit ${PROJECT_BINARY_DIR}/lib)
|
||||
ENDIF(RUN_CONFIGURE)
|
||||
ENDIF(UNIX)
|
||||
|
||||
MARK_AS_ADVANCED(ABINIT_LIBRARY)
|
||||
|
||||
#EXEC_PROGRAM(rm ${ABINITDIR} ARGS -f Makefile libabinit.a)
|
||||
#CONFIGURE_FILE(${ABINITDIR}/Makefile.in ${ABINITDIR}/Makefile)
|
||||
#EXEC_PROGRAM(make ${ABINITDIR} ARGS -f Makefile)
|
||||
#EXEC_PROGRAM(cp ${ABINITDIR} ARGS "libabinit.a ${LIBRARY_OUTPUT_PATH}/")
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# this module look for blitz++ (http://www.oonumerics.org/blitz) support
|
||||
# it will define the following values
|
||||
#
|
||||
# BLITZ_INCLUDE_PATH = where blitz/blitz.h can be found
|
||||
#
|
||||
|
||||
FIND_PATH(BLITZ_INCLUDE_PATH
|
||||
blitz/blitz.h
|
||||
/u/ac/esler/lib/blitz/include
|
||||
/home/common/lib/blitz-0.6-GCC
|
||||
/usr/apps/tools/blitz
|
||||
/usr/include
|
||||
/opt/include
|
||||
/usr/local/include
|
||||
${AUXPACKAGES}/Utilities/blitz
|
||||
)
|
||||
INCLUDE_DIRECTORIES(${BLITZ_INCLUDE_PATH})
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#
|
||||
# this module look for GSL (http://sources.redhat.com/gsl/) support
|
||||
# it will define the following values
|
||||
#
|
||||
# GSL_INCLUDE_PATH = where gsl/gsl_multimin.h can be found
|
||||
# GSL_LIBRARY = the library to link against (gsl etc)
|
||||
#
|
||||
|
||||
FIND_LIBRARY(GSL_LIBRARY
|
||||
gsl
|
||||
/u/ac/esler/lib/gsl/lib
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
FIND_LIBRARY(GSLCBLAS_LIBRARY
|
||||
gslcblas
|
||||
/u/ac/esler/lib/gsl/lib
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
FIND_PATH(GSL_INCLUDE_PATH
|
||||
gsl/gsl_vector.h
|
||||
/u/ac/esler/lib/gsl/include
|
||||
/usr/include
|
||||
/opt/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
IF(GSL_LIBRARY)
|
||||
MESSAGE(STATUS "Found GSL")
|
||||
INCLUDE_DIRECTORIES(${GSL_INCLUDE_PATH})
|
||||
SET(GSL_LIBRARY ${GSL_LIBRARY})
|
||||
ELSE(GSL_LIBRARY)
|
||||
INCLUDE_DIRECTORIES(${AUXPACKAGES}/Utilities/gsl ${AUXPACKAGES}/Utilities/gsl)
|
||||
SUBDIRS(Utilities)
|
||||
ENDIF(GSL_LIBRARY)
|
||||
|
||||
IF(GSLCBLAS_LIBRARY)
|
||||
MESSAGE(STATUS "Found GSLCBLAS")
|
||||
INCLUDE_DIRECTORIES(${GSL_INCLUDE_PATH})
|
||||
SET(GSLCBLAS_LIBRARY ${GSLCBLAS_LIBRARY})
|
||||
ELSE(GSLCBLAS_LIBRARY)
|
||||
INCLUDE_DIRECTORIES(${AUXPACKAGES}/Utilities/gslcblas ${AUXPACKAGES}/Utilities/gslcblas)
|
||||
SUBDIRS(Utilities)
|
||||
ENDIF(GSLCBLAS_LIBRARY)
|
||||
|
||||
LINK_LIBRARIES(${GSL_LIBRARY})
|
||||
LINK_LIBRARIES(${GSLCBLAS_LIBRARY})
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# this module look for HDF5 (http://hdf.ncsa.uiuc.edu) support
|
||||
# it will define the following values
|
||||
#
|
||||
# HDF5_INCLUDE_PATH = where hdf5.h can be found
|
||||
# HDF5_LIBRARY = the library to link against (hdf5 etc)
|
||||
#
|
||||
|
||||
FIND_LIBRARY(HDF5_LIBRARY
|
||||
hdf5
|
||||
/home/common/lib/hdf5/lib
|
||||
/u/ac/esler/lib/hdf5/lib
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/usr/apps/lib
|
||||
/sw/lib
|
||||
)
|
||||
FIND_PATH(HDF5_INCLUDE_PATH
|
||||
H5Ipublic.h
|
||||
/home/common/lib/hdf5/include
|
||||
/u/ac/esler/lib/hdf5/include
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/include
|
||||
/usr/apps/include
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
IF(HDF5_LIBRARY)
|
||||
MESSAGE(STATUS "Found HDF5")
|
||||
INCLUDE_DIRECTORIES(${HDF5_INCLUDE_PATH})
|
||||
SET(HDF5_LIBRARY ${HDF5_LIBRARY})
|
||||
ELSE(HDF5_LIBRARY)
|
||||
INCLUDE_DIRECTORIES(${AUXPACKAGES}/Utilities/hdf5 ${AUXPACKAGES}/Utilities/hdf5)
|
||||
SUBDIRS(Utilities)
|
||||
ENDIF(HDF5_LIBRARY)
|
||||
|
||||
LINK_LIBRARIES(${HDF5_LIBRARY})
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# this module look for libxml++ (http://libxmlplusplus.sourceforge.net) support
|
||||
# it will define the following values
|
||||
#
|
||||
# LIBXMLPP_INCLUDE_PATH = where libxml++/libxml++.h can be found
|
||||
# LIBXMLPP_LIBRARY = the library to link against
|
||||
#
|
||||
|
||||
FIND_LIBRARY(LIBXMLPP_LIBRARY xml++-1.0
|
||||
lib
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/usr/apps/lib
|
||||
/usr/apps/tools/libxml++/lib
|
||||
)
|
||||
FIND_PATH(LIBXMLPP_INCLUDE_DIR
|
||||
libxml++/libxml++.h
|
||||
/usr/apps/include/libxml++-1.0
|
||||
/usr/local/include/libxml++-1.0
|
||||
/usr/apps/tools/libxml++/include
|
||||
libxml++/libxml++.h
|
||||
include/libxml++-1.0
|
||||
)
|
||||
|
||||
IF(NOT LIBXMLPP_LIBRARY)
|
||||
IF(UNIX)
|
||||
IF(RUN_CONFIGURE)
|
||||
EXEC_PROGRAM(aclocal ${AUXPACKAGES}/libxml++)
|
||||
EXEC_PROGRAM(autoconf ${AUXPACKAGES}/libxml++)
|
||||
EXEC_PROGRAM(automake ${AUXPACKAGES}/libxml++ ARGS -a)
|
||||
EXEC_PROGRAM(
|
||||
"${AUXPACKAGES}/libxml++/configure --prefix=${PROJECT_BINARY_DIR} --with-cxx=$ENV{CXX}"
|
||||
${AUXPACKAGES}/libxml++
|
||||
)
|
||||
EXEC_PROGRAM(make ${AUXPACKAGES}/libxml++)
|
||||
EXEC_PROGRAM("make install" ${AUXPACKAGES}/libxml++)
|
||||
FIND_PATH(LIBXMLPP_INCLUDE_DIR libxml++/libxml++.h
|
||||
${PROJECT_BINARY_DIR}/include/libxml++-1.0)
|
||||
FIND_LIBRARY(LIBXMLPP_LIBRARY xml++-0.1
|
||||
${PROJECT_BINARY_DIR}/lib)
|
||||
ENDIF(RUN_CONFIGURE)
|
||||
ENDIF(UNIX)
|
||||
ENDIF(NOT LIBXMLPP_LIBRARY)
|
||||
|
||||
INCLUDE_DIRECTORIES(${LIBXMLPP_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${LIBXMLPP_LIBRARY})
|
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# this module look for libxml (http://http://xmlsoft.org) support
|
||||
# it will define the following values
|
||||
#
|
||||
# LIBXML_INCLUDE_PATH = where libxml/parser.h can be found
|
||||
# LIBXML_LIBRARY = the library to link against libxml2
|
||||
#
|
||||
|
||||
FIND_LIBRARY(LIBXML_LIBRARY xml2
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/sw/lib)
|
||||
FIND_PATH(LIBXML_INCLUDE_DIR
|
||||
libxml/parser.h
|
||||
/usr/include/libxml2
|
||||
/sw/include/libxml2
|
||||
)
|
||||
|
||||
IF(NOT LIBXML_LIBRARY)
|
||||
MESSAGE(STATUS "libxml is not found in pre-defined paths.")
|
||||
IF(UNIX)
|
||||
IF(RUN_CONFIGURE)
|
||||
EXEC_PROGRAM(
|
||||
"${AUXPACAKGES}/libxml2/configure --prefix=${PROJECT_BINARY_DIR} --with-cc=${CMAKE _CC_COMPILER}"
|
||||
${AUXPACAKGES}/libxml2
|
||||
)
|
||||
EXEC_PROGRAM(make ${AUXPACKAGES}/libxml2)
|
||||
EXEC_PROGRAM(make ${AUXPACKAGES}/libxml2 ARGS install)
|
||||
FIND_LIBRARY(LIBXML_LIBRARY xml2 ${PROJECT_BINARY_DIR}/lib)
|
||||
FIND_PATH(LIBXML_INCLUDE_DIR libxml/parser.h ${PROJECT_BINARY_DIR}/include)
|
||||
ENDIF(RUN_CONFIGURE)
|
||||
ENDIF(UNIX)
|
||||
ENDIF(NOT LIBXML_LIBRARY)
|
||||
|
||||
IF(LIBXML_LIBRARY)
|
||||
MARK_AS_ADVANCED(LIBXML_INCLUDE_DIR LIBXML_LIBRARY)
|
||||
ADD_DEFINITIONS(-DENABLE_LIBXML2)
|
||||
INCLUDE_DIRECTORIES(${LIBXML_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${LIBXML_LIBRARY})
|
||||
ENDIF(LIBXML_LIBRARY)
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
# this module look for lapack/blas and other numerical library support
|
||||
# it will define the following values
|
||||
# LAPACK_LIBRARY
|
||||
# BLAS_LIBRARY
|
||||
#
|
||||
# 1) search ENV MKL
|
||||
# 2) search MKL in usual paths
|
||||
# 3) search lapack/blas
|
||||
# 4) give up
|
||||
#
|
||||
SET(MKL_PATHS "")
|
||||
|
||||
#use environment variables
|
||||
IF(INTEL_COMPILER)
|
||||
|
||||
#use environment variables: e.g, module at OSC uses MKL
|
||||
IF($ENV{MKL} MATCHES "mkl")
|
||||
|
||||
MESSAGE(STATUS "Using intel/mkl library: $ENV{MKL}")
|
||||
|
||||
#look for the path where the mkl is installed
|
||||
STRING(REGEX MATCHALL "[-][L]([^ ;])+" MKL_PATH_WITH_PREFIX "$ENV{MKL}")
|
||||
STRING(REGEX REPLACE "[-][L]" "" MKL_PATHS ${MKL_PATH_WITH_PREFIX})
|
||||
|
||||
ENDIF($ENV{MKL} MATCHES "mkl")
|
||||
|
||||
SET(MKL_PATHS ${MKL_PATHS}
|
||||
/usr/local/intel/mkl60/mkl60/lib/64
|
||||
/usr/local/intel/mkl/lib/32
|
||||
/opt/intel/mkl/lib/32
|
||||
)
|
||||
MESSAGE(STATUS "Looking for intel/mkl library in ${MKL_PATHS}")
|
||||
|
||||
# IF($ENV{MKL}) MATCHES "mkl")
|
||||
# MESSAGE(STATUS "Using intel/mkl library: $ENV{MKL}")
|
||||
# SET(LAPACK_LIBRARY $ENV{MKL})
|
||||
# SET(BLAS_LIBRARY " ")
|
||||
# SET(LAPACK_LIBRARY_INIT 1)
|
||||
# ENDIF($ENV{MKL}) MATCHES "mkl")
|
||||
|
||||
IF(NOT LAPACK_LIBRARY_INIT)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY
|
||||
NAMES mkl_lapack
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
FIND_LIBRARY(BLAS_LIBRARY
|
||||
NAMES mkl mkl_itp
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
FIND_LIBRARY(BLAS_EXTRA_LIBRARY
|
||||
NAMES guide
|
||||
PATHS ${MKL_PATHS}
|
||||
)
|
||||
IF(LAPACK_LIBRARY MATCHES "mkl")
|
||||
MESSAGE(STATUS "Found intel/mkl library")
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
ENDIF(LAPACK_LIBRARY MATCHES "mkl")
|
||||
ENDIF(NOT LAPACK_LIBRARY_INIT)
|
||||
ENDIF(INTEL_COMPILER)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
SET(ELIB essl)
|
||||
SET(LLIB lapack-SP4_32)
|
||||
IF(ENABLE_OMP)
|
||||
SET(ELIB esslsmp)
|
||||
ENDIF(ENABLE_OMP)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY ${LLIB}
|
||||
/usr/apps/math/lapack/LAPACK
|
||||
)
|
||||
FIND_LIBRARY(BLAS_LIBRARY ${ELIB}
|
||||
/usr/lib
|
||||
)
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
MESSAGE(STATUS "Found lapack/blas on AIX system")
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
|
||||
|
||||
IF(NOT LAPACK_LIBRARY_INIT)
|
||||
FIND_LIBRARY(LAPACK_LIBRARY NAMES lapack lapack_gnu
|
||||
PATHS /usr/apps/math/lapack
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
FIND_LIBRARY(BLAS_LIBRARY NAMES blas blas_gnu
|
||||
PATHS /usr/apps/math/lapack
|
||||
/usr/lib
|
||||
/opt/lib
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
IF(LAPACK_LIBRARY AND BLAS_LIBRARY)
|
||||
MESSAGE(STATUS "Found netlib lapack/blas library")
|
||||
IF(APPLE)
|
||||
SET(BLAS_LIBRARY ${BLAS_LIBRARY} ${BLAS_EXTRA_LIBRARY} " -lcblas -latlas")
|
||||
ENDIF(APPLE)
|
||||
SET(LAPACK_LIBRARY_INIT 1 CACHE BOOL "lapack is initialized")
|
||||
ENDIF(LAPACK_LIBRARY AND BLAS_LIBRARY)
|
||||
ENDIF(NOT LAPACK_LIBRARY_INIT)
|
||||
|
||||
### BRANDT
|
||||
### MOVED BECAUSE OF SCOPE PROBLEM
|
||||
### PROBABLY SHOULD BE FIXED
|
||||
SET(BLAS_LIBRARY ${BLAS_LIBRARY} ${BLAS_EXTRA_LIBRARY})
|
||||
MARK_AS_ADVANCED(LAPACK_LIBRARY BLAS_LIBRARY BLAS_EXTRA_LIBRARY)
|
||||
#LINK_LIBRARIES(${LAPACK_LIBRARY} ${BLAS_LIBRARY})
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# this module look for HDF5 (http://hdf.ncsa.uiuc.edu) support
|
||||
# it will define the following values
|
||||
#
|
||||
# HDF5_INCLUDE_PATH = where hdf5.h can be found
|
||||
# HDF5_LIBRARY = the library to link against (hdf5 etc)
|
||||
#
|
||||
|
||||
FIND_LIBRARY(SPRNG_LIBRARY
|
||||
sprng
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
FIND_PATH(SPRNG_INCLUDE_PATH
|
||||
sprng.h
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
IF(SPRNG_LIBRARY)
|
||||
MESSAGE(STATUS "Found SPRNG library")
|
||||
INCLUDE_DIRECTORIES(${SPRNG_INCLUDE_PATH})
|
||||
ENDIF(SPRNG_LIBRARY)
|
||||
|
||||
LINK_LIBRARIES(${SPRNG_LIBRARY})
|
||||
ADD_DEFINITIONS(-DUSE_SPRNG)
|
|
@ -0,0 +1,110 @@
|
|||
PROJECT(qmcPlusPlus)
|
||||
|
||||
#define the paths for library and executable for out-of-soruce compilation
|
||||
SET (LIBRARY_OUTPUT_PATH ${qmcPlusPlus_BINARY_DIR}/lib CACHE PATH "Single output directory for building all libraries.")
|
||||
SET (EXECUTABLE_OUTPUT_PATH ${qmcPlusPlus_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables.")
|
||||
|
||||
#list of options to determine libraries. First, try to use libraries available
|
||||
SET(INTEL_COMPILER 0)
|
||||
SET(ENABLE_OPENMP 0)
|
||||
SET(HAVE_MPI 0)
|
||||
SET(HAVE_OOMPI 0)
|
||||
SET(HAVE_LIBXML2 0)
|
||||
SET(HAVE_LIBXMLPP 0)
|
||||
SET(HAVE_LIBHDF5 0)
|
||||
SET(HAVE_LIBSPRNG 0)
|
||||
SET(HAVE_LIBBLITZ 0)
|
||||
SET(HAVE_LIBGSL 0)
|
||||
|
||||
OPTION(QMC_SPRNG "Eanble SPRNG random number generation library" OFF)
|
||||
OPTION(QMC_BLITZ "Eanble blitz++ library" ON)
|
||||
|
||||
######################################################################
|
||||
#important settings for QMC simulations to instantiate template classes
|
||||
#OHMMS_* is to reuse Ohmms class libraries
|
||||
#OHMMS_DIM = dimension of the problem
|
||||
#OHMMS_INDEXTYPE = type of index
|
||||
#OHMMS_PRECISION = base precision, float, double etc
|
||||
#QMC_FASTWALKER = true, when operation is faster for each walker
|
||||
#QMC_APPS = an application to compile
|
||||
######################################################################
|
||||
SET(OHMMS_DIM 3)
|
||||
SET(OHMMS_INDEXTYPE int)
|
||||
SET(OHMMS_PRECISION double)
|
||||
SET(QMC_FASTWALKER 1)
|
||||
SET(QMCAPPS MolecuApps)
|
||||
|
||||
######################################################################
|
||||
#experimental settings for optimization
|
||||
######################################################################
|
||||
SET(INTEL_COMPILER 0)
|
||||
|
||||
SET (PROJECT_CMAKE ${qmcPlusPlus_SOURCE_DIR}/CMake)
|
||||
######################################################
|
||||
#COMPILER choose one of the cmake files to customize the compiler options
|
||||
#If nothing is chosen, default settings by cmake will be used.
|
||||
######################################################
|
||||
#INCLUDE(${PROJECT_CMAKE}/Intel8.cmake)
|
||||
#INCLUDE(${PROJECT_CMAKE}/Intel7.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/GNUCompilers.cmake)
|
||||
#INCLUDE(${PROJECT_CMAKE}/IBMCompilers.cmake)
|
||||
#INCLUDE(${PROJECT_CMAKE}/KCCCompilers.cmake)
|
||||
#INCLUDE(${PROJECT_CMAKE}/Compilers.cmake)
|
||||
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/FindThreads.cmake)
|
||||
|
||||
#check external libraries: required
|
||||
INCLUDE(${PROJECT_CMAKE}/FindLibxml2.cmake)
|
||||
#INCLUDE(${PROJECT_CMAKE}/FindLibxmlpp.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/FindLapack.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/FindHDF5.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/FindGSL.cmake)
|
||||
INCLUDE(${PROJECT_CMAKE}/FindBlitz++.cmake)
|
||||
|
||||
IF(FOUND_LIBXML2)
|
||||
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${LIBXML2_LIBRARY})
|
||||
SET(HAVE_LIBXML2 1)
|
||||
ENDIF(FOUND_LIBXML2)
|
||||
|
||||
#IF(FOUND_LIBXMLPP)
|
||||
# INCLUDE_DIRECTORIES(${LIBXMLPP_INCLUDE_DIR})
|
||||
# LINK_LIBRARIES(${LIBXMLPP_LIBRARY})
|
||||
# SET(HAVE_LIBXMLPP 1)
|
||||
#ENDIF(FOUND_LIBXMLPP)
|
||||
|
||||
IF(FOUND_HDF5)
|
||||
SET(HAVE_LIBHDF5 1)
|
||||
INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${HDF5_LIBRARY})
|
||||
ENDIF(FOUND_HDF5)
|
||||
|
||||
IF(FOUND_GSL)
|
||||
SET(HAVE_LIBGSL 1)
|
||||
INCLUDE_DIRECTORIES(${GSL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${GSL_LIBRARY})
|
||||
ENDIF(FOUND_GSL)
|
||||
|
||||
#check optional external libraries: enable only when the libraroes are found
|
||||
IF(FOUND_BLITZ)
|
||||
INCLUDE_DIRECTORIES(${BLITZ_INCLUDE_DIR})
|
||||
SET(HAVE_LIBBLITZ 1)
|
||||
ENDIF(FOUND_BLITZ)
|
||||
#IF(QMC_BLITZ)
|
||||
#ENDIF(QMC_BLITZ)
|
||||
|
||||
IF(QMC_MPI)
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/CMake/addMPI.cmake)
|
||||
ENDIF(QMC_MPI)
|
||||
|
||||
IF(QMC_SPRNG)
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/CMake/addSPRNG.cmake)
|
||||
ENDIF(QMC_SPRNG)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${qmcPlusPlus_SOURCE_DIR}/src
|
||||
${qmcPlusPlus_BINARY_DIR}/src
|
||||
)
|
||||
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
|
||||
|
||||
SUBDIRS(src)
|
|
@ -0,0 +1,52 @@
|
|||
Important Notice for qmcplusplus developers and end-users:
|
||||
|
||||
i) The original programs developed by Jeongnim Kim and her collaborators
|
||||
are distributed under UIUC/NCSA Open Source License (below).
|
||||
|
||||
ii) Some packages/features are not available under open source license and require
|
||||
separate license agreements with the authors. Contact the responsible authors.
|
||||
|
||||
iii) autoconf/automake scripts are distributed under GPL (see COPYING).
|
||||
|
||||
iv) The sources derived from any package distributed under GPL contain
|
||||
explicit acknowledgments of the original works and are distributed under GPL.
|
||||
|
||||
-------------
|
||||
University of Illinois/NCSA Open Source License
|
||||
|
||||
Copyright (c) 2003, University of Illinois Board of Trustees.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
Jeongnim Kim
|
||||
Condensed Matter Physics,
|
||||
National Center for Supercomputing Applications, University of Illinois
|
||||
Materials computation Center, University of Illinois
|
||||
http://www.mcc.uiuc.edu/qmcplusplus/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
``Software''), to deal with the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimers.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimers in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the names of the NCSA, the MCC, the University of Illinois,
|
||||
nor the names of its contributors may be used to endorse or promote
|
||||
products derived from this Software without specific prior written
|
||||
permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS WITH THE SOFTWARE.
|
|
@ -0,0 +1,12 @@
|
|||
Wed Sep 3 20:47:26 CDT 2003
|
||||
|
||||
Creating app to compile the main application qmc using cmake
|
||||
|
||||
Creating Data for input/output examples
|
||||
|
||||
Adding files for cmake (usage: cmake; make)
|
||||
|
||||
CMake directory contains modules to handle libraries.
|
||||
i) FindBlitz++.cmake
|
||||
ii) FindHDF5.cmake
|
||||
iii) FindLibxml.cmake
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
|||
PROJECT(hf)
|
||||
|
||||
#CONFIGURE_FILE(${hf_SOURCE_DIR}/../Configuration.h.in
|
||||
# ${hf_SOURCE_DIR}/../Configuration.h)
|
||||
|
||||
|
||||
SET(HFSRCS
|
||||
../Utilities/OhmmsInform.cpp
|
||||
../OhmmsApp/ProjectData.cpp
|
||||
../Platforms/sysutil.cpp
|
||||
../AtomicHF/Clebsch_Gordan.cpp
|
||||
../AtomicHF/RadialPotential.cpp
|
||||
../AtomicHF/HartreeFock.cpp
|
||||
)
|
||||
|
||||
LINK_LIBRARIES(${FORTRAN_LIBS})
|
||||
ADD_EXECUTABLE(hf ${HFSRCS})
|
||||
TARGET_LINK_LIBRARIES(hf qmcbase)
|
|
@ -0,0 +1,136 @@
|
|||
// -*- C++ -*-
|
||||
/*! \author Jordan Vincent
|
||||
* \author Curry Taylor
|
||||
* \note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
// The Clebsch_Gordan class
|
||||
//
|
||||
// Contains the Clebsch-Gordan Coefficients in the array cg
|
||||
// in the following form:
|
||||
//
|
||||
// < l1 m1; l2 m2 | L m1+m2 > <---> cg[l1][l2][L][m1+6][m2+6]
|
||||
//
|
||||
// The "+6" offsets are due to the need to index arrays from 0 to
|
||||
// whatever in C++. Therefore, for example, in the case of
|
||||
// m1 = m2 = 0, the last two indices to the cg array are both *6*.
|
||||
//
|
||||
// This routine was adopted from a FORTRAN 77 algorithm taken from
|
||||
// Rose's 'Elementary Theory of Angular Momentum', p. 39, Wigner's
|
||||
// formula. Those coefficients listed are only those for which
|
||||
// l1 >= l2. Coeffienents known to be zero (because of either the
|
||||
// L or M selection rules) are *not* computed, and these should not
|
||||
// be sought.
|
||||
//
|
||||
// Note: As the main routine is statically defined (hard-coded),
|
||||
// l values greater than 6 are not allowed and will cause error.
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "AtomicHF/Clebsch_Gordan.h"
|
||||
#include <iostream>
|
||||
|
||||
/*!\fn Clebsch_Gordan::Clebsch_Gordan(const int lmax)
|
||||
* \param lmax the maximum angular momentum
|
||||
* \brief Constructs all the Clebsch-Gordan coefficients
|
||||
for \f$ l1 <= l_{max} \f$. This routine was adopted
|
||||
from a FORTRAN 77 algorithm taken from Rose's 'Elementary
|
||||
Theory of Angular Momentum', p. 39, Wigner's formula. Those
|
||||
coefficients listed are only those for which l1 >= l2.
|
||||
Coeffienents known to be zero (because of either the
|
||||
L or M selection rules) are *not* computed, and these should not
|
||||
be sought.
|
||||
Note: the indexing of the array is as follows:
|
||||
\f[ cg(l1,l2,L,m1+Lmax,m2+Lmax) \f]
|
||||
this is due to the need to index arrays from 0 to N-1
|
||||
in C++.
|
||||
Note: As the main routine is statically defined (hard-coded),
|
||||
l values greater than 6 are not allowed and will cause error.
|
||||
*
|
||||
*/
|
||||
|
||||
Clebsch_Gordan::Clebsch_Gordan(const int lmax):Lmax(lmax){
|
||||
|
||||
int l1 = Lmax+1;
|
||||
int l2 = 2*Lmax+1;
|
||||
|
||||
cg.resize(l1,l1,l2,l2,l2);
|
||||
|
||||
// std::cout << cg.shape() << std::endl;
|
||||
|
||||
cg = 0.0;
|
||||
|
||||
build_coefficients();
|
||||
}
|
||||
|
||||
Clebsch_Gordan::~Clebsch_Gordan() { cg.free(); }
|
||||
|
||||
/*!
|
||||
* \fn void Clebsch_Gordan::build_coefficients()
|
||||
*
|
||||
* \brief Calculates the Clebsch-Gordan coefficients and stores
|
||||
them in a 5-dimensional Blitz++ array.
|
||||
*
|
||||
*/
|
||||
|
||||
void Clebsch_Gordan::build_coefficients() {
|
||||
|
||||
double si[33], fa[33], sum, prefactor;
|
||||
int lmin, i, l1, l2, l3, m1, m2, m3, nmin, nmax;
|
||||
|
||||
// lmax = maximum(n, size);
|
||||
|
||||
si[0] = 1.0;
|
||||
fa[0] = 1.0;
|
||||
|
||||
for(i=1; i<=32; i++) {
|
||||
si[i] = -si[i-1];
|
||||
fa[i] = (double)i * fa[i-1];
|
||||
}
|
||||
|
||||
for(l1=0; l1<=Lmax; l1++) {
|
||||
for(l2=0; l2<=l1; l2++) {
|
||||
for(m1=-l1; m1<=l1; m1++) {
|
||||
for(m2=-l2; m2<=l2; m2++) {
|
||||
m3 = m1 + m2;
|
||||
lmin = abs(l1-l2);
|
||||
|
||||
if(lmin < abs(m3)) { lmin = abs(m3); }
|
||||
|
||||
for(l3=lmin; l3<=l1+l2; l3++) {
|
||||
prefactor = 2.0*l3 + 1.0;
|
||||
prefactor *= fa[l3+l1-l2] / fa[l1+l2+l3+1];
|
||||
prefactor *= fa[l3-l1+l2] / fa[l1-m1];
|
||||
prefactor *= fa[l1+l2-l3] / fa[l1+m1];
|
||||
prefactor *= fa[l3+m3] / fa[l2-m2];
|
||||
prefactor *= fa[l3-m3] / fa[l2+m2];
|
||||
prefactor = sqrt(prefactor);
|
||||
|
||||
nmax = l3 - l1 + l2;
|
||||
if(l3+m3 < nmax) { nmax = l3+m3; }
|
||||
|
||||
nmin = 0;
|
||||
if(l1-l2-m3 < nmin) { nmin = -(l1-l2-m3); }
|
||||
|
||||
sum = 0;
|
||||
for(i=nmin; i<=nmax; i++) {
|
||||
sum += (si[i+l2+m2]/fa[i]) * fa[l2+l3+m1-i] * fa[l1-m1+i]
|
||||
/ fa[l3-l1+l2-i] / fa[l3+m3-i] / fa[i+l1-l2-m3];
|
||||
}
|
||||
|
||||
cg(l1,l2,l3,m1+Lmax,m2+Lmax) = prefactor*sum;
|
||||
cg(l2,l1,l3,m2+Lmax,m1+Lmax) = si[l1+l2+l3]*prefactor*sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// -*- C++ -*-
|
||||
/*! \author Jordan Vincent
|
||||
* \author Curry Taylor
|
||||
* \note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
#ifndef CLEBSCH_GORDAN_H2
|
||||
#define CLEBSCH_GORDAN_H2
|
||||
|
||||
#include <blitz/array.h>
|
||||
|
||||
/**class Clebsch_Gordan
|
||||
*\brief Calculates the Clebsch-Gordan coefficients
|
||||
*/
|
||||
class Clebsch_Gordan {
|
||||
public:
|
||||
|
||||
Clebsch_Gordan(const int lmax);
|
||||
///destructor
|
||||
~Clebsch_Gordan();
|
||||
|
||||
///maximum angular momentum
|
||||
int Lmax;
|
||||
///array to store the Clebsch-Gordan coefficients
|
||||
blitz::Array<double,5> cg;
|
||||
///returns \f$c_g(l1,l2,l3,m1,m2) \f$
|
||||
inline double operator()(int l1, int l2, int l3, int m1, int m2) const {
|
||||
return cg(l1,l2,l3,m1+Lmax,m2+Lmax);
|
||||
}
|
||||
|
||||
private:
|
||||
/// default constructor not implemented
|
||||
Clebsch_Gordan() { }
|
||||
|
||||
void build_coefficients();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_ATOMICHARTREEFOCK_TYPES_H
|
||||
#define OHMMS_ATOMICHARTREEFOCK_TYPES_H
|
||||
|
||||
#include "AtomicHF/YlmRnlSet.h"
|
||||
|
||||
/**@namespace ohmmshf
|
||||
*@brief Define basic data types for the applications.
|
||||
* In order to reduce complier-time complexity and to enable switching
|
||||
* between C++ libraries for array and expression template,
|
||||
* basic data types are defined.
|
||||
*/
|
||||
namespace ohmmshf {
|
||||
typedef YlmRnlSet<double> HFAtomicOrbitals;
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef OHMMS_MAIN_HFCONFIGURATION_H
|
||||
#define OHMMS_MAIN_HFCONFIGURATION_H
|
||||
#include <iostream>
|
||||
// #if !defined(LOGMSG)
|
||||
// #define LOGMSG(msg) {std::cout << "HF: " << msg << std::endl;}
|
||||
// #endif
|
||||
|
||||
// #if !defined(DEBUGMSG)
|
||||
// #define DEBUGMSG(msg) {std::cout << "DEBUG: " << msg << std::endl;}
|
||||
// #endif
|
||||
|
||||
// #if !defined(ERRORMSG)
|
||||
// #define ERRORMSG(msg) {std::cout << "ERROR: " << msg << std::endl;}
|
||||
// #endif
|
||||
// int Z = 0;
|
||||
|
||||
#if !defined(LOGMSG)
|
||||
#define LOGMSG(msg) {std::cout<< "QMC " << msg << std::endl;}
|
||||
#endif
|
||||
|
||||
#if !defined(WARNMSG)
|
||||
#define WARNMSG(msg) {std::cout<< "WARNING " << msg << std::endl;}
|
||||
#endif
|
||||
|
||||
#if !defined(DEBUGMSG)
|
||||
#if defined(PRINT_DEBUG)
|
||||
#define DEBUGMSG(msg) {std::cout<< "DEBUG " << msg << std::endl;}
|
||||
#else
|
||||
#define DEBUGMSG(msg)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ERRORMSG)
|
||||
#define ERRORMSG(msg) {std::cout<< "ERROR " << msg << std::endl;}
|
||||
#endif
|
||||
|
||||
#if !defined(XMLReport)
|
||||
//#if defined(PRINT_DEBUG)
|
||||
#define XMLReport(msg) {std::cout<< "XML " << msg << std::endl;}
|
||||
//#else
|
||||
//#define XMLReport(msg)
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#include "AtomicHF/HFConfiguration.h"
|
||||
#include "AtomicHF/Clebsch_Gordan.h"
|
||||
#include "AtomicHF/HartreeFock.h"
|
||||
#include "AtomicHF/fillshells.h"
|
||||
#include "OhmmsData/OhmmsElementBase.h"
|
||||
#include "OhmmsPETE/OhmmsMatrix.h"
|
||||
#include "Utilities/OhmmsSpecies.h"
|
||||
#include <fstream>
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
namespace ohmmshf {
|
||||
|
||||
bool parseXMLFile(RadialPotentialSet& Pot, HFAtomicOrbitals& Psi,
|
||||
string& name,string& pottype,string& gridtype,
|
||||
const xmlpp::Node* root) {
|
||||
using namespace xmlpp;
|
||||
int nshells = 0;
|
||||
OneDimGridBase<double>* grid;
|
||||
NodeSet aset = root->find("//Atom");
|
||||
if(aset.empty()){
|
||||
ERRORMSG("Must include atomic information.")
|
||||
return false;
|
||||
} else {
|
||||
Element* cur = dynamic_cast<Element*>(aset[0]);
|
||||
Attribute* att1 = cur->get_attribute("name");
|
||||
Attribute* att2 = cur->get_attribute("num_closed_shells");
|
||||
if(att1){
|
||||
name = att1->get_value();
|
||||
XMLReport("Name = " << name)
|
||||
} else {
|
||||
ERRORMSG("Must specify name.")
|
||||
return false;
|
||||
}
|
||||
if(att2){
|
||||
nshells = atoi(att2->get_value().c_str());
|
||||
XMLReport("Number of Closed Shells = " << nshells)
|
||||
} else {
|
||||
WARNMSG("Number of Closed Shells = " << nshells)
|
||||
}
|
||||
|
||||
NodeSet gset = aset[0]->find("./Grid");
|
||||
if(gset.empty()){
|
||||
ERRORMSG("No grid information")
|
||||
return false;
|
||||
} else {
|
||||
Element* p = dynamic_cast<Element*>(gset[0]);
|
||||
Element::AttributeList atts = p->get_attributes();
|
||||
Element::AttributeList::iterator it = atts.begin();
|
||||
|
||||
double scale = 1.0;
|
||||
double min = 0.001;
|
||||
double max = 1000.0;
|
||||
int npts = 2001;
|
||||
while(it != atts.end()) {
|
||||
const string& aname = (*it)->get_name();
|
||||
if(aname == "type") {
|
||||
gridtype = (*it)->get_value();
|
||||
} else if(aname == "scale") {
|
||||
scale = atof((*it)->get_value().c_str());
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
XMLReport("Grid type = " << gridtype)
|
||||
|
||||
NodeSet gpset = gset[0]->find("./Parameter");
|
||||
if(gpset.empty()){
|
||||
WARNMSG("Using default grid values")
|
||||
} else {
|
||||
for(int i=0; i<gpset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(gpset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(aname == "min") putContent(min,curc);
|
||||
else if(aname == "max") putContent(max,curc);
|
||||
else if(aname == "npts") putContent(npts,curc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(gridtype == "log"){
|
||||
grid = new LogGrid<double>;
|
||||
min/=scale;
|
||||
max/=sqrt(scale);
|
||||
grid->set(min,max,npts);
|
||||
XMLReport("rmin = " << min << ", rmax = " << max
|
||||
<< ", dh = " << grid->dh() << ", npts = " << npts)
|
||||
} else if(gridtype == "linear"){
|
||||
grid = new LinearGrid<double>;
|
||||
min/=scale;
|
||||
max/=sqrt(scale);
|
||||
grid->set(min,max,npts);
|
||||
XMLReport("rmin = " << min << ", rmax = " << max
|
||||
<< ", dh = " << grid->dh() << ", npts = " << npts)
|
||||
} else {
|
||||
ERRORMSG("Grid Type Options: Log or Linear.")
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
// pass grid to wavefunction
|
||||
Psi.m_grid = grid;
|
||||
// class to generate Clebsh Gordan coeff.
|
||||
Clebsch_Gordan* CG_coeff;
|
||||
|
||||
NodeSet potset = aset[0]->find("./Potential");
|
||||
if(potset.empty()){
|
||||
ERRORMSG("Must provide potential information.")
|
||||
return false;
|
||||
} else {
|
||||
Element* cur = dynamic_cast<Element*>(potset[0]);
|
||||
Attribute* att = cur->get_attribute("type");
|
||||
if(att){
|
||||
pottype = att->get_value();
|
||||
|
||||
NodeSet oset = aset[0]->find("./OrbitalSet");
|
||||
if(oset.empty()){
|
||||
ERRORMSG("Must specify OrbitalSet")
|
||||
return false;
|
||||
} else {
|
||||
Element* cur = dynamic_cast<Element*>(oset[0]);
|
||||
Attribute* att = cur->get_attribute("rest_type");
|
||||
if(att) Psi.Restriction = att->get_value();
|
||||
XMLReport("Orbital restriction type = " << Psi.Restriction)
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(pottype == "Harmonic"){
|
||||
if(nshells) FillShellsHarmPot(Psi,nshells);
|
||||
} else {
|
||||
if(nshells) FillShellsNucPot(Psi,nshells);
|
||||
}
|
||||
Psi.put(curc);
|
||||
Pot.initialize(Psi);
|
||||
LOGMSG("No of Orbs = " << Psi.size());
|
||||
|
||||
LOGMSG("Orbital | Orbital ID");
|
||||
for(int j=0; j < Psi.size(); j++){
|
||||
LOGMSG(j << " " << Psi.ID[j]);
|
||||
}
|
||||
LOGMSG("ID | IDcount");
|
||||
for(int j=0; j < Psi.NumUniqueOrb; j++){
|
||||
LOGMSG(j << " " << Psi.IDcount[j]);
|
||||
}
|
||||
}
|
||||
XMLReport("Potential Type = " << pottype)
|
||||
} else {
|
||||
ERRORMSG("Must provide Potential Type.")
|
||||
return false;
|
||||
}
|
||||
if(pottype == "Nuclear"){
|
||||
XMLReport("Creating a Nuclear Potential.")
|
||||
double Z;
|
||||
NodeSet gpset = potset[0]->find("./Parameter");
|
||||
if(gpset.empty()){
|
||||
Z = Psi.NumOrb;
|
||||
WARNMSG("Default: Z = " << Z)
|
||||
} else {
|
||||
for(int i=0; i<gpset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(gpset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(aname == "Z") putContent(Z,curc);
|
||||
XMLReport("Z = " << Z)
|
||||
}
|
||||
}
|
||||
}
|
||||
// determine maximum angular momentum
|
||||
int lmax = 0;
|
||||
for(int i=0; i<Psi.L.size(); i++)
|
||||
if(Psi.L[i] > lmax) lmax = Psi.L[i];
|
||||
XMLReport("Maximum Angular Momentum = " << lmax)
|
||||
CG_coeff = new Clebsch_Gordan(lmax);
|
||||
Pot.add(new ZOverRFunctor(Z));
|
||||
Pot.add(new HartreePotential(CG_coeff));
|
||||
Pot.add(new ExchangePotential(CG_coeff));
|
||||
Psi.CuspParam = Z;
|
||||
Psi.EigenBoundParam = Z;
|
||||
} // if Nuclear
|
||||
else if(pottype == "Harmonic"){
|
||||
XMLReport("Creating a Harmonic Potential.")
|
||||
double Omega;
|
||||
NodeSet gpset = potset[0]->find("./Parameter");
|
||||
if(gpset.empty()){
|
||||
Omega = Psi.NumOrb;
|
||||
WARNMSG("Default: Omega = " << Omega)
|
||||
} else {
|
||||
for(int i=0; i<gpset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(gpset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(aname == "Omega") putContent(Omega,curc);
|
||||
else if(aname == "Z") putContent(Omega,curc);
|
||||
XMLReport("Omega = " << Omega)
|
||||
}
|
||||
}
|
||||
}
|
||||
// determine maximum angular momentum
|
||||
int lmax = 0;
|
||||
for(int i=0; i<Psi.L.size(); i++)
|
||||
if(Psi.L[i] > lmax) lmax = Psi.L[i];
|
||||
lmax++; // increment by 1
|
||||
XMLReport("Maximum Angular Momentum = " << lmax)
|
||||
CG_coeff = new Clebsch_Gordan(lmax);
|
||||
Pot.add(new HarmonicFunctor(Omega));
|
||||
Pot.add(new HartreePotential(CG_coeff));
|
||||
Pot.add(new ExchangePotential(CG_coeff));
|
||||
Psi.CuspParam = 0.0;
|
||||
Psi.EigenBoundParam = Omega;
|
||||
} // if Harmonic
|
||||
else if(pottype == "Nuclear_Scalar_Rel"){
|
||||
XMLReport("Creating a Nuclear Scalar Relativistic Potential.")
|
||||
double Z;
|
||||
NodeSet gpset = potset[0]->find("./Parameter");
|
||||
if(gpset.empty()){
|
||||
Z = Psi.NumOrb;
|
||||
WARNMSG("Default: Z = " << Z)
|
||||
} else {
|
||||
for(int i=0; i<gpset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(gpset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(aname == "Z") putContent(Z,curc);
|
||||
XMLReport("Z = " << Z)
|
||||
}
|
||||
}
|
||||
}
|
||||
// determine maximum angular momentum
|
||||
int lmax = 0;
|
||||
for(int i=0; i<Psi.L.size(); i++)
|
||||
if(Psi.L[i] > lmax) lmax = Psi.L[i];
|
||||
XMLReport("Maximum Angular Momentum = " << lmax)
|
||||
CG_coeff = new Clebsch_Gordan(lmax);
|
||||
Pot.add(new ZOverRFunctor(Z));
|
||||
Pot.add(new HartreePotential(CG_coeff));
|
||||
Pot.add(new ExchangePotential(CG_coeff));
|
||||
Psi.CuspParam = Z;
|
||||
Psi.EigenBoundParam = Z;
|
||||
} // if Nuclear_Scalar_Rel
|
||||
else if(pottype == "Pseudo"){
|
||||
XMLReport("Creating a Starkloff-Joannopoulos Pseudo-Potential.")
|
||||
double rc, lambda, Zeff;
|
||||
NodeSet gpset = potset[0]->find("./Parameter");
|
||||
if(gpset.empty()){
|
||||
ERRORMSG("Must Provide core radius and decay for PseudoPotential.")
|
||||
return false;
|
||||
} else {
|
||||
for(int i=0; i<gpset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(gpset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* curc = cur->cobj();
|
||||
if(aname == "rc"){
|
||||
putContent(rc,curc);
|
||||
XMLReport("Core radius = " << rc)
|
||||
} else if(aname == "lambda"){
|
||||
putContent(lambda,curc);
|
||||
XMLReport("Decay = " << lambda)
|
||||
} else if(aname == "Zeff"){
|
||||
putContent(Zeff,curc);
|
||||
XMLReport("Effective core charge = " << Zeff)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// determine maximum angular momentum
|
||||
int lmax = 0;
|
||||
for(int i=0; i<Psi.L.size(); i++)
|
||||
if(Psi.L[i] > lmax) lmax = Psi.L[i];
|
||||
XMLReport("Maximum Angular Momentum = " << lmax)
|
||||
CG_coeff = new Clebsch_Gordan(lmax);
|
||||
Pot.add(new PseudoPotential(Zeff,rc,lambda));
|
||||
Pot.add(new HartreePotential(CG_coeff));
|
||||
Pot.add(new ExchangePotential(CG_coeff));
|
||||
Psi.CuspParam = 0.0;
|
||||
Psi.EigenBoundParam = 2.0*Zeff/rc;
|
||||
} // if Pseudo
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
using namespace ohmmshf;
|
||||
using namespace xmlpp;
|
||||
DomParser parser;
|
||||
parser.parse_file(argv[1]);
|
||||
Node* root
|
||||
= parser.get_document()->get_root_node(); //deleted by DomParser.
|
||||
string element;
|
||||
string pottype;
|
||||
string gridtype;
|
||||
|
||||
RadialPotentialSet Pot;
|
||||
HFAtomicOrbitals Psi;
|
||||
|
||||
parseXMLFile(Pot,Psi,element,pottype,gridtype,root);
|
||||
HartreeFock HFSolver(Pot,Psi,root);
|
||||
HFSolver.solve(pottype,gridtype,Psi.size());
|
||||
Psi.print(element);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
#ifndef OHMMS_ATOMICHF_HARTREEFOCK_H
|
||||
#define OHMMS_ATOMICHF_HARTREEFOCK_H
|
||||
#include "AtomicHF/HFConfiguration.h"
|
||||
#include "AtomicHF/HFAtomicOrbitals.h"
|
||||
#include "AtomicHF/RadialPotentialSet.h"
|
||||
#include "Numerics/RnlRelTransform.h"
|
||||
#include "Numerics/RnlTransform.h"
|
||||
#include "Numerics/HarmTransform.h"
|
||||
#include "Numerics/Numerov.h"
|
||||
#include "Numerics/RadialFunctorUtility.h"
|
||||
#include "OhmmsData/libxmldefs.h"
|
||||
#include <libxml++/libxml++.h>
|
||||
#include <ofstream>
|
||||
|
||||
namespace ohmmshf {
|
||||
|
||||
struct HartreeFock {
|
||||
|
||||
typedef HFAtomicOrbitals::value_type value_type;
|
||||
typedef HFAtomicOrbitals::RadialOrbital_t RadialOrbital_t;
|
||||
|
||||
int maxiter;
|
||||
value_type eig_tol, scf_tol, ratio;
|
||||
RadialPotentialSet& Pot;
|
||||
HFAtomicOrbitals& Psi;
|
||||
|
||||
HartreeFock(RadialPotentialSet& pot, HFAtomicOrbitals& psi,
|
||||
const xmlpp::Node* root):
|
||||
Pot(pot), Psi(psi), maxiter(1000), eig_tol(1e-12),
|
||||
scf_tol(1e-8), ratio(0.35) { put(root); }
|
||||
|
||||
|
||||
bool put(const xmlpp::Node* q){
|
||||
using namespace xmlpp;
|
||||
NodeSet eset = q->find("./EigenSolve");
|
||||
if(eset.empty()){
|
||||
WARNMSG("Using default values for eigensolver.")
|
||||
XMLReport("maximum iterations = " << maxiter)
|
||||
XMLReport("eigentolerance = " << eig_tol)
|
||||
XMLReport("scftolerance = " << scf_tol)
|
||||
XMLReport("ratio = " << ratio)
|
||||
} else {
|
||||
NodeSet pset = eset[0]->find("./Parameter");
|
||||
for(int i=0; i<pset.size(); i++){
|
||||
Element* cur = dynamic_cast<Element*>(pset[i]);
|
||||
Attribute* att = cur->get_attribute("name");
|
||||
if(att) {
|
||||
const string& aname = att->get_value();
|
||||
xmlNode* ccur = cur->cobj();
|
||||
if(aname == "max_iter"){
|
||||
putContent(maxiter,ccur);
|
||||
XMLReport("maximum iterations = " << maxiter)
|
||||
} else if(aname == "eig_tol"){
|
||||
putContent(eig_tol,ccur);
|
||||
XMLReport("eigentolerance = " << eig_tol)
|
||||
} else if(aname == "en_tol"){
|
||||
putContent(scf_tol,ccur);
|
||||
XMLReport("scftolerance = " << scf_tol)
|
||||
} else if(aname == "mix_ratio"){
|
||||
putContent(ratio,ccur);
|
||||
XMLReport("ratio = " << ratio)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Transform_t>
|
||||
void run_hf(Transform_t* fake, int norb) {
|
||||
|
||||
typedef Numerov<Transform_t, RadialOrbital_t> Numerov_t;
|
||||
value_type Vtotal,KEnew, KEold,E;
|
||||
vector<value_type> energy(Pot.size()), epsilon(norb);
|
||||
value_type lowerbound, upperbound;
|
||||
int iter = 0;
|
||||
Vtotal = Pot.evaluate(Psi,energy,norb);
|
||||
Pot.mix(0.0);
|
||||
KEnew = Pot.calcKE(Psi,0,norb);
|
||||
string label("spdf");
|
||||
|
||||
ofstream log_stream("atomicHF.log");
|
||||
log_stream.precision(8);
|
||||
|
||||
|
||||
do {
|
||||
KEold = KEnew;
|
||||
value_type eigsum = 0.0;
|
||||
///loop over the orbitals
|
||||
for(int ob=0; ob < norb; ob++){
|
||||
///set up the transformer
|
||||
Transform_t es(Pot.V[ob], Psi.N[ob], Psi.L[ob],
|
||||
Psi.CuspParam, Psi.EigenBoundParam);
|
||||
///initialize the numerov solver
|
||||
Numerov_t numerov(es,Psi(ob));
|
||||
///calculate the lower and upper bounds for the eigenvalue
|
||||
es.EnergyBound(lowerbound,upperbound);
|
||||
///perform the numerov algorithm
|
||||
///calculate the eigenvalue and the corresponding orbital
|
||||
eigsum += (epsilon[ob] =
|
||||
numerov.solve(lowerbound, upperbound, eig_tol));
|
||||
|
||||
log_stream << Psi.N[ob]<< label[Psi.L[ob]] << '\t' << epsilon[ob] << endl;
|
||||
}
|
||||
log_stream << endl;
|
||||
|
||||
///normalize the orbitals
|
||||
Psi.normalize(norb);
|
||||
///restrict the orbitals
|
||||
Psi.applyRestriction(norb);
|
||||
///calculate the new kinetic energy
|
||||
KEnew = Pot.calcKE(Psi,eigsum,norb);
|
||||
///the total energy
|
||||
E = KEnew + Vtotal;
|
||||
///for the new orbitals Psi, calculate the new SCF potentials
|
||||
Vtotal = Pot.evaluate(Psi,energy,norb);
|
||||
Pot.applyRestriction(Psi);
|
||||
Pot.mix(ratio);
|
||||
log_stream.precision(10);
|
||||
log_stream << "Iteration #" << iter+1 << endl;
|
||||
log_stream << "KE = " << setw(15) << KEnew
|
||||
<< " PE = " << setw(15) << Vtotal << endl;
|
||||
log_stream << "PE/KE = " << setw(15) << Vtotal/KEnew
|
||||
<< " Energy = " << setw(15) << E << endl;
|
||||
log_stream << endl;
|
||||
iter++;
|
||||
///continue the loop until the kinetic energy converges
|
||||
}while(fabs(KEnew-KEold)>scf_tol && iter<maxiter);
|
||||
}
|
||||
|
||||
inline void solve(string pottype, string gridtype, int norb) {
|
||||
|
||||
if(pottype == "Harmonic"){
|
||||
if(gridtype == "linear"){
|
||||
HarmLinearTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
} else if(gridtype == "log"){
|
||||
HarmLogTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
}
|
||||
} else if(pottype == "Nuclear_Scalar_Rel"){
|
||||
if(gridtype == "linear"){
|
||||
RnlRelLinearTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
} else if(gridtype == "log"){
|
||||
RnlRelLogTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
}
|
||||
} else if(pottype == "Nuclear"){
|
||||
if(gridtype == "linear"){
|
||||
RnlLinearTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
} else if(gridtype == "log"){
|
||||
RnlLogTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
}
|
||||
} else if(pottype == "Pseudo"){
|
||||
if(gridtype == "linear"){
|
||||
RnlLinearTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
} else if(gridtype == "log"){
|
||||
RnlLogTransform<RadialOrbital_t> *afake=NULL;
|
||||
run_hf(afake,norb);
|
||||
}
|
||||
} else return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
##########################################################
|
||||
# OHMMS application makefile stub for suite: linuxicc
|
||||
# Created Sat Mar 29 15:39:36 CST 2003 by jnkim on bach
|
||||
# Generated by configure --arch linuxicc --tb
|
||||
##########################################################
|
||||
include makefile.linuxicc
|
||||
|
||||
#CDIR = ../Common/IO
|
||||
|
||||
.SUFFIXES: .cpp .F .o
|
||||
|
||||
.f.o:
|
||||
$(F77) $(F77FLAGS) -c $< -o $(ODIR)/$@
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGSAPP) $(OHMMSINC) -c $< -o $@
|
||||
|
||||
BASEOBJS = $(ODIR)/OhmmsObject.o $(ODIR)/OhmmsInform.o $(ODIR)/OhmmsInfo.o $(ODIR)/Communicate.o $(ODIR)/CommCreate.o
|
||||
COMMONOBJS = $(CDIR)/InputOutput.o $(CDIR)/InputOutputASCII.o $(CDIR)/InputOutputHDF5.o
|
||||
HFOBJS = $(BASEOBJS) $(ODIR)/RadialPotential.o $(ODIR)/Clebsch_Gordan.o
|
||||
|
||||
hartreefock.x: HartreeFock.cpp $(HFOBJS)
|
||||
$(CXX) $(CXXLDFLAGS) $(OHMMSINC) -o $(ODIR)/hartreefock.x HartreeFock.cpp $(HFOBJS) $(OHMMSLIBS)
|
||||
|
||||
#PASS_DEFS = "CC=${CXX} -c" "LD=${CXX}" "CCFLAGS=${CXXFLAGSAPP}" "DEFS=${DEFS}" "INCL=${OHMMSINC}" "LIBS=${OHMMSLIBS}"
|
||||
#MAKE_ALL = $(MAKE) all $(PASS_DEFS)
|
||||
#MAKE_NEWMAKE = $(MAKE) -f template.make newmake $(PASS_DEFS)
|
||||
|
||||
#Common_obj: Common_newmake
|
||||
# cd ../Common; ${MAKE_ALL}
|
||||
#Common_newmake:
|
||||
# cd ../Common; $(MAKE_NEWMAKE)
|
||||
#Common_clean:
|
||||
# cd ../Common; ${MAKE} clean
|
||||
#clean:
|
||||
# rm -rf *.o hartreefock.x
|
||||
|
||||
include $(OHMMSDIR)/src/Utilities/Makefile
|
||||
include $(OHMMSDIR)/src/Message/Makefile
|
||||
include $(OHMMSDIR)/src/AtomicHF/Makefile
|
||||
|
||||
#include $(HFDIR)/src/Particle/Makefile
|
||||
|
||||
# ---------------------------------------------------
|
||||
# $RCSfile$Author: jnkim $
|
||||
# $Revision$Date: 2003/08/27 14:19:23 $
|
||||
# ---------------------------------------------------
|
|
@ -0,0 +1,349 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#include <math.h>
|
||||
#include "AtomicHF/RadialPotential.h"
|
||||
#include "AtomicHF/Clebsch_Gordan.h"
|
||||
#include "Numerics/RadialFunctorUtility.h"
|
||||
using namespace ohmmshf;
|
||||
|
||||
/*!
|
||||
* \fn ZOverRFunctor::ZOverRFunctor(value_type z)
|
||||
* \param z the charge of the Nuclear Potential
|
||||
* \brief The Constructor for the Nuclear Potential
|
||||
*
|
||||
*/
|
||||
|
||||
ZOverRFunctor::ZOverRFunctor(value_type z): Z(z) { }
|
||||
|
||||
/*! RadialPotentialBase::value_type
|
||||
PseudoPotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param V the potential
|
||||
* \param norb the number of orbitals
|
||||
* \return The sum of the Nuclear Potential matrix
|
||||
elements (energy): \f[
|
||||
\langle i|V(r)|i \rangle = \sum_{k=0}^{N_{orb}}
|
||||
\int_0^{\infty} dr\psi_k^*(r)V(r)\psi_k(r) \f]
|
||||
* \brief Calculates and assigns the values of the Nuclear
|
||||
Potential for each orbital. The Nuclear Potential: \f[
|
||||
V_{Nuclear}(r) = -\frac{Z}{r} \f]
|
||||
*
|
||||
*/
|
||||
|
||||
RadialPotentialBase::value_type
|
||||
ZOverRFunctor::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb){
|
||||
|
||||
RadialOrbital_t integrand(psi(0));
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++) {
|
||||
value_type t = -Z/psi.m_grid->r(ig);
|
||||
value_type sum = 0.0;
|
||||
for(int o=0; o < norb; o++) {
|
||||
V[o](ig) += t;
|
||||
sum += pow(psi(o,ig),2);
|
||||
}
|
||||
integrand(ig) = t*sum;
|
||||
}
|
||||
return integrate_RK2(integrand);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn HarmonicFunctor::HarmonicFunctor(value_type omega)
|
||||
* \param omega
|
||||
* \brief The Constructor for the Harmonic Potential
|
||||
*
|
||||
*/
|
||||
|
||||
HarmonicFunctor::HarmonicFunctor(value_type omega):
|
||||
Omega(omega) { }
|
||||
|
||||
/*! RadialPotentialBase::value_type
|
||||
PseudoPotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param V the potential
|
||||
* \param norb the number of orbitals
|
||||
* \return The sum of the Harmonic Potential matrix
|
||||
elements (energy): \f[
|
||||
\langle i|V(r)|i \rangle = \sum_{k=0}^{N_{orb}}
|
||||
\int_0^{\infty} dr\psi_k^*(r)V(r)\psi_k(r) \f]
|
||||
* \brief Calculates and assigns the values of the Harmonic
|
||||
Potential for each orbital. The Harmonic Potential: \f[
|
||||
V_{Harmonic}(r) = \frac{1}{2}\omega^2 r^2 \f]
|
||||
*
|
||||
*/
|
||||
|
||||
RadialPotentialBase::value_type
|
||||
HarmonicFunctor::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb) {
|
||||
RadialOrbital_t integrand(psi(0));
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++) {
|
||||
value_type v = 0.5*Omega*Omega*psi.m_grid->r(ig)*psi.m_grid->r(ig);
|
||||
value_type sum = 0.0;
|
||||
for(int o=0; o < norb; o++) {
|
||||
V[o](ig) += v;
|
||||
sum += pow(psi(o,ig),2);
|
||||
}
|
||||
integrand(ig) = v*sum;
|
||||
}
|
||||
return integrate_RK2(integrand);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn PseudoPotential::PseudoPotential(VarRegistry<value_type>& vreg,
|
||||
value_type zeff, value_type r_c,
|
||||
value_type lambda)
|
||||
* \param vreg a registry for the optimizable variables
|
||||
\f$r_c\$f and \f$\lambda\f$
|
||||
* \param zeff \f$Z_{Eff}\f$ the effective charge of the core
|
||||
* \param r_c \f$r_c\$f the core-radius
|
||||
* \param lambda \f$\lambda\f$ the decay parameter
|
||||
* \brief The Constructor for the Joanappoulos-Starkloff
|
||||
pseudopotential
|
||||
*
|
||||
*/
|
||||
|
||||
PseudoPotential::PseudoPotential(VarRegistry<value_type>& vreg,
|
||||
value_type zeff, value_type r_c,
|
||||
value_type lambda):
|
||||
Zeff(zeff), rc(r_c), SJ_lambda(lambda) {
|
||||
vreg.add("SJ_lambda",&SJ_lambda);
|
||||
vreg.add("r_core",&rc);
|
||||
}
|
||||
|
||||
PseudoPotential::PseudoPotential(value_type zeff, value_type r_c,
|
||||
value_type lambda):
|
||||
Zeff(zeff), rc(r_c), SJ_lambda(lambda) { }
|
||||
|
||||
/*! RadialPotentialBase::value_type
|
||||
PseudoPotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param V the potential
|
||||
* \param norb the number of orbitals
|
||||
* \return The sum of the PseudoPotential matrix elements: \f[
|
||||
\langle i|V_{PP}(r)|i \rangle = \sum_{k=0}^{N_{orb}}
|
||||
\int_0^{\infty} dr\psi_k^*(r)V_{PP}(r)\psi_k(r) \f]
|
||||
* \brief Calculates and assigns the values of the pseudopotential
|
||||
for each orbital. The Starkloff-Joannapoulos pseudopotential: \f[
|
||||
V_{PP}(r) = -\frac{Z_{Eff}}{r}\frac{1-e^{-\lambda r}}
|
||||
{1-e^{-\lambda (r-r_c)}} \f]
|
||||
*
|
||||
*/
|
||||
|
||||
RadialPotentialBase::value_type
|
||||
PseudoPotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb) {
|
||||
RadialOrbital_t integrand(psi(0));
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++) {
|
||||
value_type r = psi.m_grid->r(ig);
|
||||
value_type SJ_num = 1.0-exp(-SJ_lambda*r);
|
||||
value_type SJ_den = 1.0+exp(-SJ_lambda*(r-rc));
|
||||
value_type v = -Zeff/r*SJ_num/SJ_den;
|
||||
value_type sum = 0.0;
|
||||
for(int o=0; o < norb; o++) {
|
||||
V[o](ig) += v;
|
||||
sum += pow(psi(o,ig),2);
|
||||
}
|
||||
integrand(ig) = v*sum;
|
||||
}
|
||||
return integrate_RK2(integrand);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn HartreePotential::HartreePotential(Clebsch_Gordan* cg)
|
||||
* \param cg The Clebsch-Gordan matrix elements
|
||||
* \brief The Constructor for the HartreePotential
|
||||
*
|
||||
*/
|
||||
|
||||
HartreePotential::HartreePotential(Clebsch_Gordan* cg):
|
||||
CG_coeff(cg) { }
|
||||
|
||||
/*!
|
||||
* \fn RadialPotentialBase::value_type
|
||||
HartreePotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi The wavefuntion
|
||||
* \param V The potential
|
||||
* \param norb The number of orbitals
|
||||
* \return The sum of the Hartree matrix elements: \f[
|
||||
\langle ij|\frac{1}{r_{12}}|ij \rangle = \sum_{k=0}^{max(2l_i,2l_j)}
|
||||
c^k(l_i,m_i;l_i,m_i)c^k(l_j,m_j;l_j,m_j)R^k(i,j;i,j) \f]
|
||||
*
|
||||
* \brief Calculates and assigns the values for the Hartree potential
|
||||
for each orbital. The Hartree potential: \f[ V_{Hartree}(r) =
|
||||
\sum_j\sum_{k=0}^{max(2l_i,2l_j)} (-1)^{m_i+m_j}
|
||||
\frac{(2l_i+1)(2l_j+1)}{(2k+1)^2}c_g(l_i,l_j,k,0,0)
|
||||
c_g(l_j,l_j,k,0,0)c_g(l_i,l_i,k,-m_i,m_i)
|
||||
c_g(l_i,l_i,k,-m_j,m_j)\frac{ Y_k(n_jl_j,n_jl_j/r)}{r} \f]
|
||||
*
|
||||
*/
|
||||
|
||||
RadialPotentialBase::value_type
|
||||
HartreePotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb) {
|
||||
|
||||
int kmax, k;
|
||||
int pt;
|
||||
value_type coeff, ith_orb_coeff, jth_orb_coeff, energy_coeff = 0;
|
||||
value_type Ehartree=0;
|
||||
|
||||
RadialOrbital_t Ykii_r(psi(0));
|
||||
RadialOrbital_t Ykjj_r(psi(0));
|
||||
RadialOrbital_t Psisq_x_Yk(psi(0));
|
||||
int npts = psi.m_grid->size();
|
||||
for(int i=0; i < norb; i++) {
|
||||
|
||||
int mi = psi.M[i];
|
||||
int li = psi.L[i];
|
||||
int two_li_plus_one = 2*li + 1;
|
||||
|
||||
for(int j=i; j < norb; j++) {
|
||||
|
||||
int mj = psi.M[j];
|
||||
int lj = psi.L[j];
|
||||
int two_lj_plus_one = 2*lj + 1;
|
||||
|
||||
int kmax = (li > lj) ? 2*lj : 2*li;
|
||||
|
||||
for(int k=kmax; k >= 0; k -= 2) {
|
||||
int two_k_plus_one = 2*k+1;
|
||||
|
||||
int lmax = CG_coeff->Lmax;
|
||||
coeff = static_cast<value_type>(two_li_plus_one*two_lj_plus_one)/
|
||||
static_cast<value_type>(two_k_plus_one)/static_cast<value_type>(two_k_plus_one)
|
||||
* CG_coeff->cg(li,li,k,0+lmax,0+lmax) * CG_coeff->cg(lj,lj,k,0+lmax,0+lmax)
|
||||
* CG_coeff->cg(li,li,k,mi+lmax,-mi+lmax) * CG_coeff->cg(lj,lj,k,mj+lmax,-mj+lmax)
|
||||
* pow(-1.0, mi+mj);
|
||||
|
||||
if(i == j) coeff /= 2.0;
|
||||
|
||||
ith_orb_coeff = psi.Occ[i] * coeff;
|
||||
jth_orb_coeff = psi.Occ[j] * coeff;
|
||||
energy_coeff = psi.Occ[j] * psi.Occ[i] * coeff;
|
||||
|
||||
Ykofr(Ykii_r, psi(i), psi(i), k);
|
||||
Ykofr(Ykjj_r, psi(j), psi(j), k);
|
||||
for(int gp=0; gp<npts; gp++){
|
||||
V[i](gp) += jth_orb_coeff*Ykjj_r(gp);
|
||||
V[j](gp) += ith_orb_coeff*Ykii_r(gp);
|
||||
}
|
||||
|
||||
Ehartree += Phisq_x_Yk(Ykjj_r, psi(i), psi(i), 0.5*energy_coeff);
|
||||
Ehartree += Phisq_x_Yk(Ykii_r, psi(j), psi(j), 0.5*energy_coeff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ehartree;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn ExchangePotential::ExchangePotential(Clebsch_Gordan* cg)
|
||||
* \param cg The Clebsch-Gordan matrix elements
|
||||
* \brief The Constructor for the ExchangePotential
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
ExchangePotential::ExchangePotential(Clebsch_Gordan* cg):
|
||||
CG_coeff(cg) { }
|
||||
|
||||
/*!
|
||||
* \fn RadialPotentialBase::value_type
|
||||
ExchangePotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi The wavefuntion
|
||||
* \param V The potential
|
||||
* \param norb The number of orbitals
|
||||
* \return The sum of the Exchange matrix elements: \f[ \langle
|
||||
ij|\frac{1}{r_{12}}|ji \rangle =
|
||||
\sum_{k=|l_i-l_j|}^{l_i+l_j}c^k(l_i,m_i;l_j,m_j)R^k(ij;ji) \f]
|
||||
* \brief Calculates and assigns the values for the exchange potential
|
||||
for each orbital. The exchange potential: \f[ V_{exchange}(r) =
|
||||
\sum_j\delta(s_i,s_j)\sum_{k=|l_i-l_j|}^{l_i+l_j}
|
||||
\frac{(2l_i+1)(2l_j+1)}{(2k+1)^2}c_g(l_i,l_j,k,0,0)^2
|
||||
c_g(l_i,l_j,k,-m_i,m_j)^2\frac{ Y_k(n_il_i,n_jl_j/r)}{r} \f] is
|
||||
non-local.
|
||||
*/
|
||||
|
||||
RadialPotentialBase::value_type
|
||||
ExchangePotential::evaluate(const HFAtomicOrbitals& psi,
|
||||
RadialOrbitalSet_t& V, int norb) {
|
||||
|
||||
value_type ith_orb_coeff, jth_orb_coeff, coeff;
|
||||
value_type energy_coeff=0;
|
||||
value_type Eexchange=0;
|
||||
/// zero_all_orbitals(); V is reset before entering
|
||||
RadialOrbital_t Ykij_r(psi(0));
|
||||
|
||||
// Loop over all pairs of electrons once
|
||||
for(int i=0; i < norb; i++) {
|
||||
int si = psi.S[i];
|
||||
int mi = psi.M[i];
|
||||
int li = psi.L[i];
|
||||
int two_li_plus_one = 2*li + 1;
|
||||
|
||||
for(int j=i; j < norb; j++) {
|
||||
int sj = psi.S[j];
|
||||
int mj = psi.M[j];
|
||||
int lj = psi.L[j];
|
||||
int two_lj_plus_one = 2*lj + 1;
|
||||
|
||||
int kmax = li + lj;
|
||||
int kmin = abs(li - lj);
|
||||
|
||||
if( si == sj ) {
|
||||
for(int k=kmax; k >= kmin; k-=2) {
|
||||
int two_k_plus_one = 2*k + 1;
|
||||
|
||||
int lmax = CG_coeff->Lmax;
|
||||
coeff = static_cast<value_type>(two_li_plus_one * two_lj_plus_one) /
|
||||
static_cast<value_type>(two_k_plus_one*two_k_plus_one)
|
||||
* CG_coeff->cg(li,lj,k,0+lmax,0+lmax) * CG_coeff->cg(li,lj,k,-mi+lmax,mj+lmax)
|
||||
* CG_coeff->cg(li,lj,k,0+lmax,0+lmax) * CG_coeff->cg(li,lj,k,-mi+lmax,mj+lmax);
|
||||
|
||||
if(i == j) coeff /= 2.0;
|
||||
|
||||
ith_orb_coeff = psi.Occ[i] * coeff;
|
||||
jth_orb_coeff = psi.Occ[j] * coeff;
|
||||
energy_coeff = psi.Occ[j] * psi.Occ[i] * coeff;
|
||||
|
||||
Ykofr(Ykij_r, psi(i), psi(j), k); /// Ykofr_phi1_phi2
|
||||
|
||||
Make_Loc_Pot(V[i], Ykij_r, psi(i), psi(j),jth_orb_coeff);
|
||||
Make_Loc_Pot(V[j], Ykij_r, psi(j), psi(i),ith_orb_coeff);
|
||||
|
||||
Eexchange -= Phisq_x_Yk(Ykij_r, psi(i), psi(j), energy_coeff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Eexchange;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMSHF_RADIALPOTENTIALBASE_H
|
||||
#define OHMMSHF_RADIALPOTENTIALBASE_H
|
||||
|
||||
#include "AtomicHF/HFAtomicOrbitals.h"
|
||||
#include "Optimize/VarList.h"
|
||||
/*! \author Jeongnim Kim
|
||||
* \author Jordan Vincent
|
||||
* \note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
|
||||
class Clebsch_Gordan;
|
||||
|
||||
namespace ohmmshf {
|
||||
|
||||
/**class RadialPotentialBase
|
||||
*\brief An abstract class to build grid potentials
|
||||
*/
|
||||
struct RadialPotentialBase {
|
||||
|
||||
typedef HFAtomicOrbitals::value_type value_type;
|
||||
typedef HFAtomicOrbitals::RadialGrid_t RadialGrid_t;
|
||||
typedef HFAtomicOrbitals::RadialOrbital_t RadialOrbital_t;
|
||||
typedef HFAtomicOrbitals::RadialOrbitalSet_t RadialOrbitalSet_t;
|
||||
|
||||
///constructor
|
||||
RadialPotentialBase() {}
|
||||
|
||||
///destructor
|
||||
virtual ~RadialPotentialBase() { }
|
||||
|
||||
/*! \fn virtual
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param V the potential
|
||||
* \param norb the number of orbitals
|
||||
|
||||
*/
|
||||
virtual
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb) = 0;
|
||||
};
|
||||
|
||||
/**class ZOverRFunctor
|
||||
*\brief Implements the Nuclear potential
|
||||
*/
|
||||
struct ZOverRFunctor: public RadialPotentialBase {
|
||||
value_type Z;
|
||||
ZOverRFunctor(value_type z);
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb);
|
||||
};
|
||||
|
||||
/**class HarmonicFunctor
|
||||
*\brief Implements the Harmonic potential
|
||||
*/
|
||||
struct HarmonicFunctor: public RadialPotentialBase {
|
||||
value_type Omega;
|
||||
HarmonicFunctor(value_type omega);
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb);
|
||||
};
|
||||
|
||||
/**class PseudoPotential
|
||||
*\brief Implements the Starkloff-Joanappoulos
|
||||
pseudopotential
|
||||
*/
|
||||
struct PseudoPotential: public RadialPotentialBase {
|
||||
value_type Zeff, SJ_lambda, rc;
|
||||
PseudoPotential(VarRegistry<value_type>&,value_type,
|
||||
value_type,value_type);
|
||||
PseudoPotential(value_type,value_type,value_type);
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t&V, int norb);
|
||||
};
|
||||
|
||||
|
||||
/**class HartreePotential
|
||||
*\brief Implements the Hartree potential
|
||||
*/
|
||||
struct HartreePotential: public RadialPotentialBase {
|
||||
Clebsch_Gordan *CG_coeff;
|
||||
HartreePotential(Clebsch_Gordan*);
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb);
|
||||
};
|
||||
|
||||
/**class ExchangePotential
|
||||
*\brief Implements the exchange potential
|
||||
*/
|
||||
struct ExchangePotential: public RadialPotentialBase {
|
||||
Clebsch_Gordan *CG_coeff;
|
||||
ExchangePotential(Clebsch_Gordan*);
|
||||
value_type evaluate(const HFAtomicOrbitals& mo,
|
||||
RadialOrbitalSet_t& V, int norb);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Vincent Jordan
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_RADIALPOTENTIALSET_H
|
||||
#define OHMMS_RADIALPOTENTIALSET_H
|
||||
#include "AtomicHF/RadialPotential.h"
|
||||
#include "Numerics/OneDimIntegration.h"
|
||||
namespace ohmmshf {
|
||||
|
||||
struct RadialPotentialSet {
|
||||
|
||||
typedef RadialPotentialBase::value_type value_type;
|
||||
typedef RadialPotentialBase::RadialOrbital_t RadialOrbital_t;
|
||||
typedef RadialPotentialBase::RadialGrid_t RadialGrid_t;
|
||||
|
||||
///the grid potentials for each orbital
|
||||
RadialPotentialBase::RadialOrbitalSet_t V;
|
||||
///the grid potentials for each orbital
|
||||
RadialPotentialBase::RadialOrbitalSet_t Vsave;
|
||||
///the Self Consistent Fields
|
||||
vector<RadialPotentialBase*> SCF;
|
||||
|
||||
///constructor
|
||||
RadialPotentialSet() { }
|
||||
|
||||
///destructor
|
||||
~RadialPotentialSet() {
|
||||
for(int i=0; i<SCF.size(); i++) delete SCF[i];
|
||||
}
|
||||
|
||||
///add a new Self Consistent Field to the list
|
||||
void add(RadialPotentialBase* a) { SCF.push_back(a);}
|
||||
|
||||
///return the number of Self Consistent Fields
|
||||
inline int size() const {return SCF.size();}
|
||||
|
||||
///create a grid potential for each orbital in the wavefunction
|
||||
void initialize(HFAtomicOrbitals& psi) {
|
||||
for(int i=0; i < psi.size(); i++)
|
||||
V.push_back(RadialOrbital_t(psi.m_grid));
|
||||
for(int i=0; i<psi.size(); i++)
|
||||
Vsave.push_back(RadialOrbital_t(psi.m_grid));
|
||||
}
|
||||
|
||||
///reset the grid potentials to zero
|
||||
void reset(HFAtomicOrbitals& psi) {
|
||||
for(int i=0; i<V.size(); i++){
|
||||
V[i].m_Y = 0.0;
|
||||
Vsave[i].m_Y = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \fn inline value_type evaluate(HFAtomicOrbitals& psi,
|
||||
vector<value_type>& Energy,
|
||||
int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param Energy vector to store the sum of each SCF of
|
||||
the SCF matrix elements
|
||||
* \param norb number of orbitals
|
||||
* \brief Loop over all the SCFs to generate a new
|
||||
potential for each orbital.
|
||||
*/
|
||||
|
||||
inline value_type evaluate(HFAtomicOrbitals& psi,
|
||||
vector<value_type>& Energy,
|
||||
int norb) {
|
||||
value_type sum = 0.0;
|
||||
for(int i=0; i < V.size(); i++)
|
||||
V[i].m_Y = 0.0;
|
||||
for(int ip=0; ip<SCF.size(); ip++)
|
||||
sum += (Energy[ip] = SCF[ip]->evaluate(psi,V,norb));
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*! \fn inline void mix(value_type x)
|
||||
* \param x the mixing ratio
|
||||
* \brief Mix the old potential with the new
|
||||
potential: \f[ V_{New}(r) = (1-x)V_{New}(r) +
|
||||
x V_{Old}(r). \f] This is for convergence purposes, so
|
||||
that the convergence is "smoother" and decreases the
|
||||
possibility of having dramatic changes in the potential.
|
||||
*/
|
||||
|
||||
inline void mix(value_type x) {
|
||||
value_type y = 1-x;
|
||||
for(int ob=0; ob < V.size(); ob++) {
|
||||
V[ob].m_Y = y*V[ob].m_Y + x*Vsave[ob].m_Y;
|
||||
Vsave[ob].m_Y = V[ob].m_Y;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \fn inline value_type calcKE(HFAtomicOrbitals& psi,
|
||||
value_type eigsum,
|
||||
int norb)
|
||||
* \param psi the wavefunction
|
||||
* \param eigsum the sum of the eigenvalues
|
||||
* \param norb the number of orbitals
|
||||
* \return the total kinetic energy
|
||||
* \brief Calculates the total kinetic energy:
|
||||
\f[ KE = \sum_i^{Norb} \left\{ \epsilon_i - \int_0^{\infty}
|
||||
dr \psi_i V(r) \psi_i \right\}. \f] This is true because
|
||||
\f[ \langle \psi_i | -\frac{1}{2} \nabla^2 | \psi_i \rangle
|
||||
= -\frac{1}{2r^2}\frac{d}{dr}\left( r^2 \frac{d}{dr} -
|
||||
\frac{l(l+1)}{2r^2} = (\epsilon - V(r)) \f]
|
||||
*/
|
||||
|
||||
inline value_type calcKE(HFAtomicOrbitals& psi,
|
||||
value_type eigsum,
|
||||
int norb){
|
||||
value_type sum=0.0;
|
||||
RadialOrbital_t integrand(psi(0));
|
||||
for(int ob=0; ob < norb; ob++) {
|
||||
for(int i=0; i < integrand.size(); i++){
|
||||
integrand(i) = V[ob](i)*psi(ob,i)*psi(ob,i);
|
||||
}
|
||||
sum+=integrate_RK2(integrand);
|
||||
}
|
||||
return eigsum-sum;
|
||||
}
|
||||
|
||||
/*! \fn void applyRestriction(HFAtomicOrbitals& psi)
|
||||
* \param psi the wavefunction
|
||||
* \brief Restrict the potential. Normally each orbital
|
||||
\f$ \psi_i \f$ in the wavefunction has its own unique
|
||||
potential, but we want to restrict the potential to be
|
||||
the same for orbitals with the same quantum numbers,
|
||||
such as \f$ (n,l) \f$. What this function does is
|
||||
assign the average potential to all the orbitals that
|
||||
are restricted to be the same.
|
||||
*/
|
||||
|
||||
void applyRestriction(HFAtomicOrbitals& psi){
|
||||
|
||||
static vector<value_type> sum;
|
||||
|
||||
if(sum.empty()){
|
||||
sum.resize(psi.m_grid->size());
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++)
|
||||
sum[ig] = 0.0;
|
||||
}
|
||||
|
||||
///index of starting orbital index
|
||||
int o_start = 0;
|
||||
///index of ending orbital index
|
||||
int o_end = 0;
|
||||
///orbital index
|
||||
int orb = 0;
|
||||
while (orb < psi.size()) {
|
||||
///loop over unique orbitals
|
||||
for(int uorb=0; uorb < psi.NumUniqueOrb; uorb++){
|
||||
///for each unique orbital, loop over all
|
||||
///identical orbitals
|
||||
for(int i=0; i < psi.IDcount[uorb]; i++){
|
||||
///add all the orbitals together for averaging
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++){
|
||||
sum[ig] += V[orb](ig);
|
||||
}
|
||||
///increment the orbital index
|
||||
orb++;
|
||||
}
|
||||
int o_end = o_start+psi.IDcount[uorb];
|
||||
|
||||
///assign the average back to the orbitals
|
||||
for(int o = o_start; o < o_end; o++){
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++){
|
||||
V[o](ig) = sum[ig]/psi.IDcount[uorb];
|
||||
}
|
||||
}
|
||||
o_start = o_end;
|
||||
///reset the sum for the next average
|
||||
for(int ig=0; ig < psi.m_grid->size(); ig++) sum[ig] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,327 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
/*@author Jeongnim Kim and Jordan Vincent
|
||||
*/
|
||||
#ifndef OHMMS_YLMRNLSET_ONGRID_IO_H
|
||||
#define OHMMS_YLMRNLSET_ONGRID_IO_H
|
||||
|
||||
#include "Numerics/HDFNumericAttrib.h"
|
||||
#include "Numerics/Transform2GridFunctor.h"
|
||||
|
||||
/**@brief Print \f$ r R_{nl}(r)\f$ */
|
||||
template<class GT>
|
||||
bool YlmRnlSet<GT>::get(std::ostream& os) {
|
||||
os.precision(12);
|
||||
os.setf(ios::scientific, ios::floatfield);
|
||||
for(int i=0; i < m_grid->size(); i++) {
|
||||
os << setw(20) << m_grid->r(i);
|
||||
for(int ob=0; ob < psi.size(); ob++) {
|
||||
os << setw(20) << psi[ob](i);
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \fn template<class GT>
|
||||
bool YlmRnlSet<GT>::put(xmlNodePtr cur)
|
||||
* \param cur
|
||||
* \return true if succeeds
|
||||
* \brief Loops through the XML tree to find all the orbitals,
|
||||
checks to see if the orbital has not already been added,
|
||||
and adds any new orbitals to the orbital list.
|
||||
*/
|
||||
|
||||
template<class GT>
|
||||
bool YlmRnlSet<GT>::put(xmlNodePtr cur){
|
||||
|
||||
int n;
|
||||
int l;
|
||||
int m;
|
||||
int s;
|
||||
value_type occ;
|
||||
|
||||
cur = cur->xmlChildrenNode;
|
||||
while(cur != NULL) {
|
||||
if (!(xmlStrcmp(cur->name, (const xmlChar *) "Orbital"))) {
|
||||
LOGMSG("Found Orbital");
|
||||
n = atoi((const char*)xmlGetProp(cur, (const xmlChar *) "n"));
|
||||
if(n < 0) {
|
||||
ERRORMSG("Invalid value for n");
|
||||
return false;
|
||||
}
|
||||
l = atoi((const char*)xmlGetProp(cur, (const xmlChar *) "l"));
|
||||
if(l < 0) {
|
||||
ERRORMSG( "Invalid value for l");
|
||||
return false;
|
||||
}
|
||||
|
||||
m = atoi((const char*)xmlGetProp(cur, (const xmlChar *) "m"));
|
||||
if(m < -l && m > 1) {
|
||||
ERRORMSG( "Invalid value for m");
|
||||
return false;
|
||||
}
|
||||
|
||||
s = atoi((const char*)xmlGetProp(cur, (const xmlChar *) "s"));
|
||||
if(s != 1 && s != -1) {
|
||||
ERRORMSG( "Invalid value for spin");
|
||||
return false;
|
||||
}
|
||||
occ = atof((const char*)xmlGetProp(cur, (const xmlChar *) "c"));
|
||||
if(static_cast<int>(occ) !=0 && static_cast<int>(occ) != 1) {
|
||||
ERRORMSG( "Invalid value for occupation");
|
||||
return false;
|
||||
}
|
||||
|
||||
NLMSIndex nlms(n,l,m,s);
|
||||
NLMS_Map_t::iterator it = OccNo.find(nlms);
|
||||
if(it == OccNo.end()) {
|
||||
add(n,l,m,s,occ);
|
||||
LOGMSG("Adding Orbital: n=" << n << ", l=" << l <<
|
||||
", m=" << m << ", s=" << s << ", occ=" << occ);
|
||||
// OccNo[nlmn] = Num-1;
|
||||
OccNo[nlms] = 1;
|
||||
} else {
|
||||
ERRORMSG( "Error, orbital " << n << l << m << s
|
||||
<< " already occupied");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \fn template<class GT>
|
||||
bool YlmRnlSet<GT>::print(const std::string& elementName)
|
||||
* \param elementName name of the element
|
||||
* \return true if succeeds
|
||||
* \brief The output files produced by this function are
|
||||
for use in a Quantum Monte Carlo code and for graphical
|
||||
purposes only. Prints the grid and orbital information to an HDF5
|
||||
file named "elementName.h5". Also prints the basis information
|
||||
to a file named "elementName.basis.xml" and the individual
|
||||
orbitals to ASCII files named "ORB.N.L.(M).(S).elementName",
|
||||
where N,L,M,S are the quantum numbers (M,S are only printed
|
||||
if the orbitals are unrestricted). In the ASCII files, the
|
||||
orbitals are first interpolated onto a linear grid of 500
|
||||
points for reasons of disk-space.
|
||||
*/
|
||||
|
||||
template<class GT>
|
||||
bool YlmRnlSet<GT>::print(const std::string& elementName){
|
||||
|
||||
/// print to file fname
|
||||
string HDFfname = elementName + ".h5";
|
||||
hid_t afile = H5Fcreate(HDFfname.c_str(),H5F_ACC_TRUNC,
|
||||
H5P_DEFAULT,H5P_DEFAULT);
|
||||
|
||||
OneDimGridBase<double>* reduced_grid;
|
||||
reduced_grid = new LinearGrid<double>;
|
||||
ofstream* out;
|
||||
|
||||
int orbindex = 0;
|
||||
/// main group
|
||||
hid_t group_id = H5Gcreate(afile,"radial_basis_states",0);
|
||||
/// output grid information
|
||||
hid_t group_id_grid = H5Gcreate(group_id,"grid",0);
|
||||
Vector<int> grid_type(1);
|
||||
Vector<double> grid_params(3);
|
||||
grid_params[0] = m_grid->rmin();
|
||||
grid_params[1] = m_grid->rmax();
|
||||
grid_params[2] = static_cast<double>(m_grid->size());
|
||||
|
||||
// if(gridtype == "linear")
|
||||
// grid_type[0] = 1;
|
||||
// else if(gridtype == "log")
|
||||
grid_type[0] = 2;
|
||||
//HDFAttribIO<string> GridHDFTypeOut(gridtype);
|
||||
//GridHDFTypeOut.write(group_id_grid,"grid_type");
|
||||
HDFAttribIO<Vector<int> > GridHDFTypeOut(grid_type);
|
||||
GridHDFTypeOut.write(group_id_grid,"grid_type");
|
||||
HDFAttribIO<Vector<double> > GridHDFParamOut(grid_params);
|
||||
GridHDFParamOut.write(group_id_grid,"params");
|
||||
H5Gclose(group_id_grid);
|
||||
/// output orbital information
|
||||
/// output only unique radial functions
|
||||
for(int orb=0; orb<NumUniqueOrb; orb++){
|
||||
char grpname[128];
|
||||
sprintf(grpname,"orbital%04d",orb);
|
||||
hid_t group_id_orb = H5Gcreate(group_id,grpname,0);
|
||||
|
||||
Vector<int> Power(1);
|
||||
Power[0] = 1+L[orbindex];
|
||||
HDFAttribIO<Vector<int> > PowerHDFOut(Power);
|
||||
PowerHDFOut.write(group_id_orb,"power");
|
||||
|
||||
Vector<int> QuantumNo(3);
|
||||
QuantumNo[0] = N[orbindex];
|
||||
QuantumNo[1] = L[orbindex];
|
||||
// only single-zeta basis
|
||||
QuantumNo[2] = 1;
|
||||
HDFAttribIO<Vector<int> > QuantumNoHDFOut(QuantumNo);
|
||||
QuantumNoHDFOut.write(group_id_orb,"quantum_numbers");
|
||||
///vector to store the radial orbital
|
||||
Vector<double> rad_orb;
|
||||
|
||||
///create the ASCII file
|
||||
char sfname[128];
|
||||
if(Restriction == "none")
|
||||
sprintf(sfname,"ORB.%01d.%01d.%01d.%01d.%01s",N[orbindex],L[orbindex],
|
||||
M[orbindex],S[orbindex],elementName.c_str());
|
||||
else
|
||||
sprintf(sfname,"ORB.%01d.%01d.%01s",N[orbindex],L[orbindex],
|
||||
elementName.c_str());
|
||||
|
||||
out = new ofstream(sfname);
|
||||
|
||||
int max_rad = m_grid->size()-1;
|
||||
while(fabs(psi[orbindex](max_rad)) < 1e-12) max_rad--;
|
||||
max_rad += 2;
|
||||
rad_orb.resize(max_rad);
|
||||
reduced_grid->set(0.0,m_grid->r(max_rad),max_rad);
|
||||
RadialOrbital_t temp_orb(reduced_grid);
|
||||
for(int i=0; i<rad_orb.size(); i++)
|
||||
rad_orb(i) = psi[orbindex](i);
|
||||
///calculate the boundary conditions
|
||||
int imin = 0;
|
||||
value_type deriv = (psi[orbindex](imin+1) - psi[orbindex](imin))/m_grid->dr(imin);
|
||||
psi[orbindex].spline(imin,deriv,max_rad,0.0);
|
||||
Transform2GridFunctor<OneDimGridFunctor<double>,OneDimGridFunctor<double> >
|
||||
transform(psi[orbindex],temp_orb);
|
||||
transform.generate();
|
||||
for(int j=0; j<reduced_grid->size(); j++)
|
||||
*out << setw(15) << temp_orb.r(j) << setw(15) << temp_orb(j) << endl;
|
||||
out->close();
|
||||
|
||||
HDFAttribIO<Vector<double> > RadOrbOut(rad_orb);
|
||||
RadOrbOut.write(group_id_orb,"radial_orbital");
|
||||
|
||||
H5Gclose(group_id_orb);
|
||||
orbindex += IDcount[orb];
|
||||
|
||||
}
|
||||
|
||||
H5Gclose(group_id);
|
||||
H5Fclose(afile);
|
||||
|
||||
/// create input for qmc
|
||||
int nUp = 0;
|
||||
int nDn = 0;
|
||||
int nBasis = 0;
|
||||
ofstream* osXML;
|
||||
string fnameXML = elementName + ".basis.xml";
|
||||
osXML = new ofstream(fnameXML.c_str());
|
||||
*osXML << "<DeterminantSet type=\"MolecularOrbital\">" << endl;
|
||||
*osXML << "<BasisSet>" << endl;
|
||||
*osXML << "<Basis type=\"HFNG\" species=\"" << elementName
|
||||
<< "\" file=\"" << HDFfname << "\">" << endl;
|
||||
|
||||
|
||||
if(Restriction == "none"){
|
||||
for(int orb=0; orb<size(); orb++){
|
||||
(S[orb] == 1) ? nUp++ : nDn++;
|
||||
nBasis++;
|
||||
char idname[128];
|
||||
sprintf(idname,"R%03d",ID[orb]);
|
||||
*osXML << "<psi id=\"" << idname << "\" n=\"" << N[orb]
|
||||
<< "\" l=\"" << L[orb] << "\" m=\"" << M[orb]
|
||||
<< "\" s=\"" << S[orb] << "\" zeta=\"1\"/>" << endl;
|
||||
}
|
||||
} else {
|
||||
for(int orb=0; orb<size(); orb++){
|
||||
(S[orb] == 1) ? nUp++ : nDn++;
|
||||
if(S[orb] == 1){
|
||||
nBasis++;
|
||||
char idname[128];
|
||||
sprintf(idname,"R%03d",ID[orb]);
|
||||
*osXML << "<psi id=\"" << idname << "\" n=\"" << N[orb]
|
||||
<< "\" l=\"" << L[orb] << "\" m=\"" << M[orb]
|
||||
<< "\" s=\"" << S[orb] << "\" zeta=\"1\"/>" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*osXML << "</Basis>" << endl;
|
||||
*osXML << "</BasisSet>" << endl;
|
||||
*osXML << "<SlaterDeterminant>" << endl;
|
||||
*osXML << "<Determinant spin=\"1\" orbitals=\"" << nUp << "\">" << endl;
|
||||
*osXML << "<Var type=\"Array\">" << endl;
|
||||
Matrix<double> M_Up(nUp,nBasis);
|
||||
if(Restriction == "none"){
|
||||
int row = 0;
|
||||
orbindex = 0;
|
||||
for(int j=0; j<M_Up.cols(); j++){
|
||||
if(S[orbindex] == 1){
|
||||
M_Up(row,j) = 1.0;
|
||||
row++;
|
||||
}
|
||||
orbindex += IDcount[j];
|
||||
}
|
||||
} else {
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
while(row < M_Up.rows()){
|
||||
M_Up(row,col) = 1.0;
|
||||
row++; col++;
|
||||
}
|
||||
}
|
||||
*osXML << M_Up;
|
||||
*osXML << "</Var>" << endl;
|
||||
*osXML << "</Determinant>" << endl;
|
||||
*osXML << "<Determinant spin=\"-1\" orbitals=\"" << nDn << "\">" << endl;
|
||||
*osXML << "<Var type=\"Array\">" << endl;
|
||||
Matrix<double> M_Dn(nDn,nBasis);
|
||||
if(Restriction == "none"){
|
||||
orbindex = 0;
|
||||
int row = 0;
|
||||
for(int j=0; j<M_Dn.cols(); j++){
|
||||
if(S[orbindex] == -1){
|
||||
M_Dn(row,j) = 1.0;
|
||||
row++;
|
||||
}
|
||||
orbindex += IDcount[j];
|
||||
}
|
||||
} else {
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
while(row < M_Dn.rows()){
|
||||
M_Dn(row,col) = 1.0;
|
||||
row++; col++;
|
||||
}
|
||||
}
|
||||
*osXML << M_Dn;
|
||||
*osXML << "</Var>" << endl;
|
||||
*osXML << "</Determinant>" << endl;
|
||||
*osXML << "</SlaterDeterminant>" << endl;
|
||||
*osXML << "</DeterminantSet>" << endl;
|
||||
|
||||
delete osXML;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
#ifndef OHMMS_YLMRNLSET_ONGRID_CPP_H
|
||||
#define OHMMS_YLMRNLSET_ONGRID_CPP_H
|
||||
|
||||
/*! \fn template<class GT>
|
||||
bool YlmRnlSet<GT>::add(int n, int l, int m, int s, value_type occ)
|
||||
* \param n principal quantum number
|
||||
* \param l angular momentum
|
||||
* \param m z-component of angular momentum
|
||||
* \param s spin
|
||||
* \param occ occupation
|
||||
* \return true if succeeds
|
||||
* \brief Add a new orbital with quantum numbers \f$ (n,l,m,s) \f$ to
|
||||
the list of orbitals. The orbitals are sorted by their restriction
|
||||
type, i.e. if the restriction type is \f$ (n,l) \f$ "spin+space" then
|
||||
all the orbitals with the same \f$ (n,l) \f$ are grouped together.
|
||||
Each orbital is assigned an id, with the possibility of several
|
||||
orbitals sharing the same id if they are restricted.
|
||||
*/
|
||||
|
||||
template<class GT>
|
||||
bool YlmRnlSet<GT>::add(int n, int l, int m, int s, value_type occ) {
|
||||
if(Restriction == "spin+space") {
|
||||
NLIndex nl(n,l);
|
||||
NL_Map_t::iterator it = NL.find(nl);
|
||||
///if the orbital is new add it to the end of the list
|
||||
if(it == NL.end()) {
|
||||
///assign the orbital a new id
|
||||
ID.push_back(NumUniqueOrb);
|
||||
///the id counter is set to 1
|
||||
IDcount.push_back(1);
|
||||
///add a new element to the map
|
||||
NL[nl] = NumUniqueOrb;
|
||||
///increment the number of unique orbitals
|
||||
NumUniqueOrb++;
|
||||
///now add the radial grid orbital
|
||||
psi.push_back(RadialOrbital_t(m_grid));
|
||||
///add the quantum numbers to the list
|
||||
N.push_back(n);
|
||||
L.push_back(l);
|
||||
M.push_back(m);
|
||||
S.push_back(s);
|
||||
Occ.push_back(occ);
|
||||
} else {
|
||||
///if an orbital of the same restriction type has already
|
||||
///been added, add the orbital such that all the
|
||||
///orbitals with the same restriction type are grouped
|
||||
///together
|
||||
///increment the id counter
|
||||
IDcount[(*it).second]++;
|
||||
///locate the position in the array where the orbital
|
||||
///will be added
|
||||
// IDmap.resize(IDcount.size());
|
||||
vector<int> IDmap(IDcount.size());
|
||||
IDmap[0] = 0;
|
||||
int sum = 0;
|
||||
for(int i=1; i < IDmap.size(); i++){
|
||||
sum += IDcount[i-1];
|
||||
IDmap[i] = sum;
|
||||
}
|
||||
ID.insert(ID.begin()+IDmap[(*it).second],(*it).second);
|
||||
psi.insert(psi.begin()+IDmap[(*it).second],RadialOrbital_t(m_grid));
|
||||
N.insert(N.begin()+IDmap[(*it).second],n);
|
||||
L.insert(L.begin()+IDmap[(*it).second],l);
|
||||
M.insert(M.begin()+IDmap[(*it).second],m);
|
||||
S.insert(S.begin()+IDmap[(*it).second],s);
|
||||
Occ.insert(Occ.begin()+IDmap[(*it).second],occ);
|
||||
IDmap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(Restriction == "spin") {
|
||||
NLMIndex nlm(n,l,m);
|
||||
NLM_Map_t::iterator it = NLM.find(nlm);
|
||||
if(it == NLM.end()) {
|
||||
ID.push_back(NumUniqueOrb);
|
||||
IDcount.push_back(1);
|
||||
NLM[nlm] = NumUniqueOrb;
|
||||
NumUniqueOrb++;
|
||||
psi.push_back(RadialOrbital_t(m_grid));
|
||||
N.push_back(n);
|
||||
L.push_back(l);
|
||||
M.push_back(m);
|
||||
S.push_back(s);
|
||||
Occ.push_back(occ);
|
||||
} else {
|
||||
IDcount[(*it).second]++;
|
||||
vector<int> IDmap(IDcount.size());
|
||||
// IDmap.resize(IDcount.size());
|
||||
IDmap[0] = 0;
|
||||
int sum = 0;
|
||||
for(int i=1; i < IDmap.size(); i++){
|
||||
sum += IDcount[i-1];
|
||||
IDmap[i] = sum;
|
||||
}
|
||||
ID.insert(ID.begin()+IDmap[(*it).second],(*it).second);
|
||||
psi.insert(psi.begin()+IDmap[(*it).second],RadialOrbital_t(m_grid));
|
||||
N.insert(N.begin()+IDmap[(*it).second],n);
|
||||
L.insert(L.begin()+IDmap[(*it).second],l);
|
||||
M.insert(M.begin()+IDmap[(*it).second],m);
|
||||
S.insert(S.begin()+IDmap[(*it).second],s);
|
||||
Occ.insert(Occ.begin()+IDmap[(*it).second],occ);
|
||||
IDmap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(Restriction == "none") {
|
||||
///add the orbital at the end of the list
|
||||
ID.push_back(NumUniqueOrb);
|
||||
IDcount.push_back(1);
|
||||
NumUniqueOrb++;
|
||||
psi.push_back(RadialOrbital_t(m_grid));
|
||||
N.push_back(n);
|
||||
L.push_back(l);
|
||||
M.push_back(m);
|
||||
S.push_back(s);
|
||||
Occ.push_back(occ);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class GT>
|
||||
void YlmRnlSet<GT>::applyRestriction(int norb){
|
||||
|
||||
static vector<value_type> sum;
|
||||
|
||||
if(sum.empty()){
|
||||
sum.resize(m_grid->size());
|
||||
for(int ig=0; ig < m_grid->size(); ig++)
|
||||
sum[ig] = 0.0;
|
||||
}
|
||||
|
||||
int o_start = 0;
|
||||
int o_end = 0;
|
||||
int orb = 0;
|
||||
while (orb < norb) {
|
||||
for(int uorb=0; uorb < NumUniqueOrb; uorb++){
|
||||
for(int i=0; i < IDcount[uorb]; i++){
|
||||
for(int ig=0; ig < m_grid->size(); ig++){
|
||||
sum[ig] += psi[orb](ig);
|
||||
}
|
||||
orb++;
|
||||
}
|
||||
int o_end = o_start+IDcount[uorb];
|
||||
|
||||
for(int o = o_start; o < o_end; o++){
|
||||
for(int ig=0; ig < m_grid->size(); ig++){
|
||||
psi[o](ig) = sum[ig]/IDcount[uorb];
|
||||
}
|
||||
}
|
||||
o_start = o_end;
|
||||
for(int ig=0; ig < m_grid->size(); ig++) sum[ig] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,215 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
/*@author Jeongnim Kim and Jordan Vincent
|
||||
*/
|
||||
#ifndef OHMMS_YLMRNLSET_ONGRID_H
|
||||
#define OHMMS_YLMRNLSET_ONGRID_H
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include "OhmmsData/OhmmsElementBase.h"
|
||||
#include "Numerics/OneDimGridFunctor.h"
|
||||
#include "Numerics/OneDimCubicSpline.h"
|
||||
#include "Numerics/OneDimIntegration.h"
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
|
||||
|
||||
struct ltnlm {
|
||||
bool operator()(const TinyVector<int,3>& a,
|
||||
const TinyVector<int,3>& b) const {
|
||||
|
||||
if(a[0] > b[0])
|
||||
return false;
|
||||
else if(a[0] == b[0]){
|
||||
// return a[1] < b[1];
|
||||
if (a[1] < b[1]) return true;
|
||||
else if(a[1] == b[1])
|
||||
return a[2] < b[2];
|
||||
else return true;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct ltnl {
|
||||
bool operator()(const TinyVector<int,2>& a,
|
||||
const TinyVector<int,2>& b) const {
|
||||
if(a[0] > b[0])
|
||||
return false;
|
||||
else if(a[0] == b[0]){
|
||||
return a[1] < b[1];
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned D>
|
||||
struct equal_nlms {
|
||||
|
||||
bool operator()(const TinyVector<int,D>& a,
|
||||
const TinyVector<int,D>& b) const {
|
||||
int i=0;
|
||||
while(i<D) {
|
||||
if(a[i]!= b[i]) return true;
|
||||
i++;}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
struct YlmRnlSet {
|
||||
|
||||
typedef T value_type;
|
||||
typedef OneDimGridBase<value_type> RadialGrid_t;
|
||||
typedef OneDimCubicSpline<value_type,value_type> RadialOrbital_t;
|
||||
typedef vector<RadialOrbital_t> RadialOrbitalSet_t;
|
||||
|
||||
typedef TinyVector<int,2> NLIndex;
|
||||
typedef TinyVector<int,3> NLMIndex;
|
||||
typedef TinyVector<int,4> NLMSIndex;
|
||||
|
||||
typedef std::map<NLIndex,int,ltnl > NL_Map_t;
|
||||
typedef std::map<NLMIndex,int,ltnlm > NLM_Map_t;
|
||||
typedef std::map<NLMSIndex,int,equal_nlms<4> > NLMS_Map_t;
|
||||
|
||||
///constructor
|
||||
YlmRnlSet(): m_grid(NULL), NumOrb(0),
|
||||
NumUniqueOrb(0), Restriction("none"), CuspParam(0.0),
|
||||
EigenBoundParam(0.0) { }
|
||||
|
||||
bool add(int n, int l, int m, int s, value_type occ);
|
||||
|
||||
void applyRestriction(int norb);
|
||||
|
||||
///normailize all the orbitals
|
||||
void normalize(int norb){
|
||||
for(int i=0; i < norb; i++) normalize_RK2(psi[i]);
|
||||
}
|
||||
|
||||
///assigns orbital \f$ \psi_{iorb}(r) \f$
|
||||
inline RadialOrbital_t& operator()(int iorb) {
|
||||
return psi[iorb];
|
||||
}
|
||||
|
||||
///returns a reference to orbital \f$ \psi_{iorb}(r) \f$
|
||||
inline const RadialOrbital_t& operator()(int iorb) const {
|
||||
return psi[iorb];
|
||||
}
|
||||
|
||||
///return the number of orbitals
|
||||
inline int size() const { return psi.size(); }
|
||||
|
||||
///return \f$ \psi_{iorb}(r_j) \f$
|
||||
inline value_type operator()(int iorb, int j) const{
|
||||
return psi[iorb](j);
|
||||
}
|
||||
|
||||
///assigns orbital \f$ \psi_{iorb}(r_j) \f$
|
||||
inline value_type& operator()(int iorb, int j){
|
||||
return psi[iorb](j);
|
||||
}
|
||||
|
||||
inline const value_type dR0(int iorb){
|
||||
return psi[iorb].yprime0;
|
||||
}
|
||||
|
||||
inline const value_type dRN(int iorb){
|
||||
return psi[iorb].yprimeN;
|
||||
}
|
||||
|
||||
///reset the values of orbitals
|
||||
void reset() {
|
||||
for(int i=0; i < psi.size(); i++) psi[i].m_Y = 0.0;
|
||||
}
|
||||
|
||||
///restriction type;
|
||||
string Restriction;
|
||||
|
||||
///number of orbitals
|
||||
int NumOrb;
|
||||
|
||||
///number of unique orbitals
|
||||
int NumUniqueOrb;
|
||||
|
||||
///a common grid
|
||||
RadialGrid_t* m_grid;
|
||||
|
||||
/**@defgroup QuantumNumber
|
||||
* Quantum numbers of an orbital.
|
||||
* The i-th orbital is represented by (N[i],L[i],M[i],S[i])
|
||||
*@{n = Principal quantum number
|
||||
*/
|
||||
vector<int> N;
|
||||
|
||||
/*@ l = angular momentum */
|
||||
vector<int> L;
|
||||
|
||||
/*@ M = z-angular momentum */
|
||||
vector<int> M;
|
||||
|
||||
/*@ S = spin in unit of 1/2 */
|
||||
vector<int> S;
|
||||
|
||||
/**@}*///end of group QuantumNumber
|
||||
|
||||
///coefficient for each orbtial (1 if occupied, 0 if not)
|
||||
vector<value_type> Occ;
|
||||
|
||||
///parameter for calculating orbital cusp conditions
|
||||
value_type CuspParam;
|
||||
|
||||
///parameter for calculating orbital cusp conditions
|
||||
value_type EigenBoundParam;
|
||||
|
||||
///map for nl quantum numbers
|
||||
NL_Map_t NL;
|
||||
///map for nlm quantum numbers
|
||||
NLM_Map_t NLM;
|
||||
///map for occupation number
|
||||
NLMS_Map_t OccNo;
|
||||
|
||||
///assign an id for each orbital
|
||||
vector<int> ID;
|
||||
///keeps track of the number of orbitals with the same id
|
||||
vector<int> IDcount;
|
||||
// vector<int> IDmap;
|
||||
///the radial grid orbitals
|
||||
vector<RadialOrbital_t> psi;
|
||||
|
||||
bool put(xmlNodePtr cur);
|
||||
bool get(std::ostream& os);
|
||||
// bool getqmc(std::ostream& os);
|
||||
// bool getsiesta(std::ostream& os, int orb);
|
||||
bool print(const std::string&);
|
||||
};
|
||||
#include "AtomicHF/YlmRnlSet.cpp"
|
||||
#include "AtomicHF/YlmRnlSet.IO.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,657 @@
|
|||
#ifndef ATOMICHF_FILLSHELLS_H
|
||||
#define ATOMICHF_FILLSHELLS_H
|
||||
#include "AtomicHF/HFAtomicOrbitals.h"
|
||||
|
||||
using namespace ohmmshf;
|
||||
|
||||
inline void FillShellsNucPot(HFAtomicOrbitals& mo,
|
||||
int nmax) {
|
||||
// vector<int>& cs,
|
||||
// vector<double>& cratio){
|
||||
int up=1;
|
||||
int dn=-1;
|
||||
|
||||
switch(nmax) {
|
||||
case(1):
|
||||
mo.add(1,0,0,up,1.0);
|
||||
mo.add(1,0,0,dn,1.0);
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
break;
|
||||
|
||||
case(2):
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
break;
|
||||
|
||||
case(3):
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,0, 0,up,1.0);
|
||||
mo.add(3,0, 0,dn,1.0);
|
||||
mo.add(3,1,-1,up,1.0);
|
||||
mo.add(3,1,-1,dn,1.0);
|
||||
mo.add(3,1, 0,up,1.0);
|
||||
mo.add(3,1, 0,dn,1.0);
|
||||
mo.add(3,1, 1,up,1.0);
|
||||
mo.add(3,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case(4):
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,0, 0,up,1.0);
|
||||
mo.add(3,0, 0,dn,1.0);
|
||||
mo.add(3,1,-1,up,1.0);
|
||||
mo.add(3,1,-1,dn,1.0);
|
||||
mo.add(3,1, 0,up,1.0);
|
||||
mo.add(3,1, 0,dn,1.0);
|
||||
mo.add(3,1, 1,up,1.0);
|
||||
mo.add(3,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,2,-2,up,1.0);
|
||||
mo.add(3,2,-2,dn,1.0);
|
||||
mo.add(3,2,-1,up,1.0);
|
||||
mo.add(3,2,-1,dn,1.0);
|
||||
mo.add(3,2, 0,up,1.0);
|
||||
mo.add(3,2, 0,dn,1.0);
|
||||
mo.add(3,2, 1,up,1.0);
|
||||
mo.add(3,2, 1,dn,1.0);
|
||||
mo.add(3,2, 2,up,1.0);
|
||||
mo.add(3,2, 2,dn,1.0);
|
||||
mo.add(4,0, 0,up,1.0);
|
||||
mo.add(4,0, 0,dn,1.0);
|
||||
mo.add(4,1,-1,up,1.0);
|
||||
mo.add(4,1,-1,dn,1.0);
|
||||
mo.add(4,1, 0,up,1.0);
|
||||
mo.add(4,1, 0,dn,1.0);
|
||||
mo.add(4,1, 1,up,1.0);
|
||||
mo.add(4,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
break;
|
||||
|
||||
|
||||
case(5):
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,0, 0,up,1.0);
|
||||
mo.add(3,0, 0,dn,1.0);
|
||||
mo.add(3,1,-1,up,1.0);
|
||||
mo.add(3,1,-1,dn,1.0);
|
||||
mo.add(3,1, 0,up,1.0);
|
||||
mo.add(3,1, 0,dn,1.0);
|
||||
mo.add(3,1, 1,up,1.0);
|
||||
mo.add(3,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,2,-2,up,1.0);
|
||||
mo.add(3,2,-2,dn,1.0);
|
||||
mo.add(3,2,-1,up,1.0);
|
||||
mo.add(3,2,-1,dn,1.0);
|
||||
mo.add(3,2, 0,up,1.0);
|
||||
mo.add(3,2, 0,dn,1.0);
|
||||
mo.add(3,2, 1,up,1.0);
|
||||
mo.add(3,2, 1,dn,1.0);
|
||||
mo.add(3,2, 2,up,1.0);
|
||||
mo.add(3,2, 2,dn,1.0);
|
||||
mo.add(4,0, 0,up,1.0);
|
||||
mo.add(4,0, 0,dn,1.0);
|
||||
mo.add(4,1,-1,up,1.0);
|
||||
mo.add(4,1,-1,dn,1.0);
|
||||
mo.add(4,1, 0,up,1.0);
|
||||
mo.add(4,1, 0,dn,1.0);
|
||||
mo.add(4,1, 1,up,1.0);
|
||||
mo.add(4,1, 1,dn,1.0);
|
||||
|
||||
mo.add(4,2,-2,up,1.0);
|
||||
mo.add(4,2,-2,dn,1.0);
|
||||
mo.add(4,2,-1,up,1.0);
|
||||
mo.add(4,2,-1,dn,1.0);
|
||||
mo.add(4,2, 0,up,1.0);
|
||||
mo.add(4,2, 0,dn,1.0);
|
||||
mo.add(4,2, 1,up,1.0);
|
||||
mo.add(4,2, 1,dn,1.0);
|
||||
mo.add(4,2, 2,up,1.0);
|
||||
mo.add(4,2, 2,dn,1.0);
|
||||
mo.add(5,0, 0,up,1.0);
|
||||
mo.add(5,0, 0,dn,1.0);
|
||||
mo.add(5,1,-1,up,1.0);
|
||||
mo.add(5,1,-1,dn,1.0);
|
||||
mo.add(5,1, 0,up,1.0);
|
||||
mo.add(5,1, 0,dn,1.0);
|
||||
mo.add(5,1, 1,up,1.0);
|
||||
mo.add(5,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
// cs[5] = 54;
|
||||
// cratio[5] = 0.5;
|
||||
break;
|
||||
|
||||
|
||||
case(6):
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,0, 0,up,1.0);
|
||||
mo.add(3,0, 0,dn,1.0);
|
||||
mo.add(3,1,-1,up,1.0);
|
||||
mo.add(3,1,-1,dn,1.0);
|
||||
mo.add(3,1, 0,up,1.0);
|
||||
mo.add(3,1, 0,dn,1.0);
|
||||
mo.add(3,1, 1,up,1.0);
|
||||
mo.add(3,1, 1,dn,1.0);
|
||||
|
||||
mo.add(3,2,-2,up,1.0);
|
||||
mo.add(3,2,-2,dn,1.0);
|
||||
mo.add(3,2,-1,up,1.0);
|
||||
mo.add(3,2,-1,dn,1.0);
|
||||
mo.add(3,2, 0,up,1.0);
|
||||
mo.add(3,2, 0,dn,1.0);
|
||||
mo.add(3,2, 1,up,1.0);
|
||||
mo.add(3,2, 1,dn,1.0);
|
||||
mo.add(3,2, 2,up,1.0);
|
||||
mo.add(3,2, 2,dn,1.0);
|
||||
mo.add(4,0, 0,up,1.0);
|
||||
mo.add(4,0, 0,dn,1.0);
|
||||
mo.add(4,1,-1,up,1.0);
|
||||
mo.add(4,1,-1,dn,1.0);
|
||||
mo.add(4,1, 0,up,1.0);
|
||||
mo.add(4,1, 0,dn,1.0);
|
||||
mo.add(4,1, 1,up,1.0);
|
||||
mo.add(4,1, 1,dn,1.0);
|
||||
|
||||
mo.add(4,2,-2,up,1.0);
|
||||
mo.add(4,2,-2,dn,1.0);
|
||||
mo.add(4,2,-1,up,1.0);
|
||||
mo.add(4,2,-1,dn,1.0);
|
||||
mo.add(4,2, 0,up,1.0);
|
||||
mo.add(4,2, 0,dn,1.0);
|
||||
mo.add(4,2, 1,up,1.0);
|
||||
mo.add(4,2, 1,dn,1.0);
|
||||
mo.add(4,2, 2,up,1.0);
|
||||
mo.add(4,2, 2,dn,1.0);
|
||||
mo.add(5,0, 0,up,1.0);
|
||||
mo.add(5,0, 0,dn,1.0);
|
||||
mo.add(5,1,-1,up,1.0);
|
||||
mo.add(5,1,-1,dn,1.0);
|
||||
mo.add(5,1, 0,up,1.0);
|
||||
mo.add(5,1, 0,dn,1.0);
|
||||
mo.add(5,1, 1,up,1.0);
|
||||
mo.add(5,1, 1,dn,1.0);
|
||||
|
||||
mo.add(4,3,-3,up,1.0);
|
||||
mo.add(4,3,-3,dn,1.0);
|
||||
mo.add(4,3,-2,up,1.0);
|
||||
mo.add(4,3,-2,dn,1.0);
|
||||
mo.add(4,3,-1,up,1.0);
|
||||
mo.add(4,3,-1,dn,1.0);
|
||||
mo.add(4,3, 0,up,1.0);
|
||||
mo.add(4,3, 0,dn,1.0);
|
||||
mo.add(4,3, 1,up,1.0);
|
||||
mo.add(4,3, 1,dn,1.0);
|
||||
mo.add(4,3, 2,up,1.0);
|
||||
mo.add(4,3, 2,dn,1.0);
|
||||
mo.add(4,3, 3,up,1.0);
|
||||
mo.add(4,3, 3,dn,1.0);
|
||||
|
||||
mo.add(5,2,-2,up,1.0);
|
||||
mo.add(5,2,-2,dn,1.0);
|
||||
mo.add(5,2,-1,up,1.0);
|
||||
mo.add(5,2,-1,dn,1.0);
|
||||
mo.add(5,2, 0,up,1.0);
|
||||
mo.add(5,2, 0,dn,1.0);
|
||||
mo.add(5,2, 1,up,1.0);
|
||||
mo.add(5,2, 1,dn,1.0);
|
||||
mo.add(5,2, 2,up,1.0);
|
||||
mo.add(5,2, 2,dn,1.0);
|
||||
mo.add(6,0, 0,up,1.0);
|
||||
mo.add(6,0, 0,dn,1.0);
|
||||
mo.add(6,1,-1,up,1.0);
|
||||
mo.add(6,1,-1,dn,1.0);
|
||||
mo.add(6,1, 0,up,1.0);
|
||||
mo.add(6,1, 0,dn,1.0);
|
||||
mo.add(6,1, 1,up,1.0);
|
||||
mo.add(6,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
// cs[5] = 54;
|
||||
// cratio[5] = 0.5;
|
||||
// cs[6] = 86;
|
||||
// cratio[6] = 0.55;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void FillShellsHarmPot(HFAtomicOrbitals& mo,
|
||||
int nmax) {
|
||||
// vector<int>& cs,
|
||||
// vector<double>& cratio){
|
||||
|
||||
int up=1;
|
||||
int dn=-1;
|
||||
|
||||
switch(nmax) {
|
||||
case(1):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
break;
|
||||
|
||||
case(2):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
|
||||
mo.add(0,1,-1,up,1.0);
|
||||
mo.add(0,1,-1,dn,1.0);
|
||||
mo.add(0,1, 0,up,1.0);
|
||||
mo.add(0,1, 0,dn,1.0);
|
||||
mo.add(0,1, 1,up,1.0);
|
||||
mo.add(0,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
break;
|
||||
|
||||
case(3):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
|
||||
mo.add(0,1,-1,up,1.0);
|
||||
mo.add(0,1,-1,dn,1.0);
|
||||
mo.add(0,1, 0,up,1.0);
|
||||
mo.add(0,1, 0,dn,1.0);
|
||||
mo.add(0,1, 1,up,1.0);
|
||||
mo.add(0,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,2,-2,up,1.0);
|
||||
mo.add(0,2,-2,dn,1.0);
|
||||
mo.add(0,2,-1,up,1.0);
|
||||
mo.add(0,2,-1,dn,1.0);
|
||||
mo.add(0,2, 0,up,1.0);
|
||||
mo.add(0,2, 0,dn,1.0);
|
||||
mo.add(0,2, 1,up,1.0);
|
||||
mo.add(0,2, 1,dn,1.0);
|
||||
mo.add(0,2, 2,up,1.0);
|
||||
mo.add(0,2, 2,dn,1.0);
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
break;
|
||||
|
||||
case(4):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
|
||||
mo.add(0,1,-1,up,1.0);
|
||||
mo.add(0,1,-1,dn,1.0);
|
||||
mo.add(0,1, 0,up,1.0);
|
||||
mo.add(0,1, 0,dn,1.0);
|
||||
mo.add(0,1, 1,up,1.0);
|
||||
mo.add(0,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,2,-2,up,1.0);
|
||||
mo.add(0,2,-2,dn,1.0);
|
||||
mo.add(0,2,-1,up,1.0);
|
||||
mo.add(0,2,-1,dn,1.0);
|
||||
mo.add(0,2, 0,up,1.0);
|
||||
mo.add(0,2, 0,dn,1.0);
|
||||
mo.add(0,2, 1,up,1.0);
|
||||
mo.add(0,2, 1,dn,1.0);
|
||||
mo.add(0,2, 2,up,1.0);
|
||||
mo.add(0,2, 2,dn,1.0);
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(0,3,-3,up,1.0);
|
||||
mo.add(0,3,-3,dn,1.0);
|
||||
mo.add(0,3,-2,up,1.0);
|
||||
mo.add(0,3,-2,dn,1.0);
|
||||
mo.add(0,3,-1,up,1.0);
|
||||
mo.add(0,3,-1,dn,1.0);
|
||||
mo.add(0,3, 0,up,1.0);
|
||||
mo.add(0,3, 0,dn,1.0);
|
||||
mo.add(0,3, 1,up,1.0);
|
||||
mo.add(0,3, 1,dn,1.0);
|
||||
mo.add(0,3, 2,up,1.0);
|
||||
mo.add(0,3, 2,dn,1.0);
|
||||
mo.add(0,3, 3,up,1.0);
|
||||
mo.add(0,3, 3,dn,1.0);
|
||||
mo.add(1,1,-1,up,1.0);
|
||||
mo.add(1,1,-1,dn,1.0);
|
||||
mo.add(1,1, 0,up,1.0);
|
||||
mo.add(1,1, 0,dn,1.0);
|
||||
mo.add(1,1, 1,up,1.0);
|
||||
mo.add(1,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
break;
|
||||
|
||||
case(5):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
|
||||
mo.add(0,1,-1,up,1.0);
|
||||
mo.add(0,1,-1,dn,1.0);
|
||||
mo.add(0,1, 0,up,1.0);
|
||||
mo.add(0,1, 0,dn,1.0);
|
||||
mo.add(0,1, 1,up,1.0);
|
||||
mo.add(0,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,2,-2,up,1.0);
|
||||
mo.add(0,2,-2,dn,1.0);
|
||||
mo.add(0,2,-1,up,1.0);
|
||||
mo.add(0,2,-1,dn,1.0);
|
||||
mo.add(0,2, 0,up,1.0);
|
||||
mo.add(0,2, 0,dn,1.0);
|
||||
mo.add(0,2, 1,up,1.0);
|
||||
mo.add(0,2, 1,dn,1.0);
|
||||
mo.add(0,2, 2,up,1.0);
|
||||
mo.add(0,2, 2,dn,1.0);
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(0,3,-3,up,1.0);
|
||||
mo.add(0,3,-3,dn,1.0);
|
||||
mo.add(0,3,-2,up,1.0);
|
||||
mo.add(0,3,-2,dn,1.0);
|
||||
mo.add(0,3,-1,up,1.0);
|
||||
mo.add(0,3,-1,dn,1.0);
|
||||
mo.add(0,3, 0,up,1.0);
|
||||
mo.add(0,3, 0,dn,1.0);
|
||||
mo.add(0,3, 1,up,1.0);
|
||||
mo.add(0,3, 1,dn,1.0);
|
||||
mo.add(0,3, 2,up,1.0);
|
||||
mo.add(0,3, 2,dn,1.0);
|
||||
mo.add(0,3, 3,up,1.0);
|
||||
mo.add(0,3, 3,dn,1.0);
|
||||
mo.add(1,1,-1,up,1.0);
|
||||
mo.add(1,1,-1,dn,1.0);
|
||||
mo.add(1,1, 0,up,1.0);
|
||||
mo.add(1,1, 0,dn,1.0);
|
||||
mo.add(1,1, 1,up,1.0);
|
||||
mo.add(1,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,4,-4,up,1.0);
|
||||
mo.add(0,4,-4,dn,1.0);
|
||||
mo.add(0,4,-3,up,1.0);
|
||||
mo.add(0,4,-3,dn,1.0);
|
||||
mo.add(0,4,-2,up,1.0);
|
||||
mo.add(0,4,-2,dn,1.0);
|
||||
mo.add(0,4,-1,up,1.0);
|
||||
mo.add(0,4,-1,dn,1.0);
|
||||
mo.add(0,4, 0,up,1.0);
|
||||
mo.add(0,4, 0,dn,1.0);
|
||||
mo.add(0,4, 1,up,1.0);
|
||||
mo.add(0,4, 1,dn,1.0);
|
||||
mo.add(0,4, 2,up,1.0);
|
||||
mo.add(0,4, 2,dn,1.0);
|
||||
mo.add(0,4, 3,up,1.0);
|
||||
mo.add(0,4, 3,dn,1.0);
|
||||
mo.add(0,4, 4,up,1.0);
|
||||
mo.add(0,4, 4,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
|
||||
mo.add(1,2,-2,up,1.0);
|
||||
mo.add(1,2,-2,dn,1.0);
|
||||
mo.add(1,2,-1,up,1.0);
|
||||
mo.add(1,2,-1,dn,1.0);
|
||||
mo.add(1,2, 0,up,1.0);
|
||||
mo.add(1,2, 0,dn,1.0);
|
||||
mo.add(1,2, 1,up,1.0);
|
||||
mo.add(1,2, 1,dn,1.0);
|
||||
mo.add(1,2, 2,up,1.0);
|
||||
mo.add(1,2, 2,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
// cs[5] = 54;
|
||||
// cratio[5] = 0.5;
|
||||
break;
|
||||
|
||||
case(6):
|
||||
mo.add(0,0,0,up,1.0);
|
||||
mo.add(0,0,0,dn,1.0);
|
||||
|
||||
mo.add(0,1,-1,up,1.0);
|
||||
mo.add(0,1,-1,dn,1.0);
|
||||
mo.add(0,1, 0,up,1.0);
|
||||
mo.add(0,1, 0,dn,1.0);
|
||||
mo.add(0,1, 1,up,1.0);
|
||||
mo.add(0,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,2,-2,up,1.0);
|
||||
mo.add(0,2,-2,dn,1.0);
|
||||
mo.add(0,2,-1,up,1.0);
|
||||
mo.add(0,2,-1,dn,1.0);
|
||||
mo.add(0,2, 0,up,1.0);
|
||||
mo.add(0,2, 0,dn,1.0);
|
||||
mo.add(0,2, 1,up,1.0);
|
||||
mo.add(0,2, 1,dn,1.0);
|
||||
mo.add(0,2, 2,up,1.0);
|
||||
mo.add(0,2, 2,dn,1.0);
|
||||
mo.add(1,0, 0,up,1.0);
|
||||
mo.add(1,0, 0,dn,1.0);
|
||||
|
||||
mo.add(0,3,-3,up,1.0);
|
||||
mo.add(0,3,-3,dn,1.0);
|
||||
mo.add(0,3,-2,up,1.0);
|
||||
mo.add(0,3,-2,dn,1.0);
|
||||
mo.add(0,3,-1,up,1.0);
|
||||
mo.add(0,3,-1,dn,1.0);
|
||||
mo.add(0,3, 0,up,1.0);
|
||||
mo.add(0,3, 0,dn,1.0);
|
||||
mo.add(0,3, 1,up,1.0);
|
||||
mo.add(0,3, 1,dn,1.0);
|
||||
mo.add(0,3, 2,up,1.0);
|
||||
mo.add(0,3, 2,dn,1.0);
|
||||
mo.add(0,3, 3,up,1.0);
|
||||
mo.add(0,3, 3,dn,1.0);
|
||||
mo.add(1,1,-1,up,1.0);
|
||||
mo.add(1,1,-1,dn,1.0);
|
||||
mo.add(1,1, 0,up,1.0);
|
||||
mo.add(1,1, 0,dn,1.0);
|
||||
mo.add(1,1, 1,up,1.0);
|
||||
mo.add(1,1, 1,dn,1.0);
|
||||
|
||||
mo.add(0,4,-4,up,1.0);
|
||||
mo.add(0,4,-4,dn,1.0);
|
||||
mo.add(0,4,-3,up,1.0);
|
||||
mo.add(0,4,-3,dn,1.0);
|
||||
mo.add(0,4,-2,up,1.0);
|
||||
mo.add(0,4,-2,dn,1.0);
|
||||
mo.add(0,4,-1,up,1.0);
|
||||
mo.add(0,4,-1,dn,1.0);
|
||||
mo.add(0,4, 0,up,1.0);
|
||||
mo.add(0,4, 0,dn,1.0);
|
||||
mo.add(0,4, 1,up,1.0);
|
||||
mo.add(0,4, 1,dn,1.0);
|
||||
mo.add(0,4, 2,up,1.0);
|
||||
mo.add(0,4, 2,dn,1.0);
|
||||
mo.add(0,4, 3,up,1.0);
|
||||
mo.add(0,4, 3,dn,1.0);
|
||||
mo.add(0,4, 4,up,1.0);
|
||||
mo.add(0,4, 4,dn,1.0);
|
||||
|
||||
mo.add(2,0, 0,up,1.0);
|
||||
mo.add(2,0, 0,dn,1.0);
|
||||
|
||||
mo.add(1,2,-2,up,1.0);
|
||||
mo.add(1,2,-2,dn,1.0);
|
||||
mo.add(1,2,-1,up,1.0);
|
||||
mo.add(1,2,-1,dn,1.0);
|
||||
mo.add(1,2, 0,up,1.0);
|
||||
mo.add(1,2, 0,dn,1.0);
|
||||
mo.add(1,2, 1,up,1.0);
|
||||
mo.add(1,2, 1,dn,1.0);
|
||||
mo.add(1,2, 2,up,1.0);
|
||||
mo.add(1,2, 2,dn,1.0);
|
||||
|
||||
mo.add(0,5,-5,up,1.0);
|
||||
mo.add(0,5,-5,dn,1.0);
|
||||
mo.add(0,5,-4,up,1.0);
|
||||
mo.add(0,5,-4,dn,1.0);
|
||||
mo.add(0,5,-3,up,1.0);
|
||||
mo.add(0,5,-3,dn,1.0);
|
||||
mo.add(0,5,-2,up,1.0);
|
||||
mo.add(0,5,-2,dn,1.0);
|
||||
mo.add(0,5,-1,up,1.0);
|
||||
mo.add(0,5,-1,dn,1.0);
|
||||
mo.add(0,5, 0,up,1.0);
|
||||
mo.add(0,5, 0,dn,1.0);
|
||||
mo.add(0,5, 1,up,1.0);
|
||||
mo.add(0,5, 1,dn,1.0);
|
||||
mo.add(0,5, 2,up,1.0);
|
||||
mo.add(0,5, 2,dn,1.0);
|
||||
mo.add(0,5, 3,up,1.0);
|
||||
mo.add(0,5, 3,dn,1.0);
|
||||
mo.add(0,5, 4,up,1.0);
|
||||
mo.add(0,5, 4,dn,1.0);
|
||||
mo.add(0,5, 5,up,1.0);
|
||||
mo.add(0,5, 5,dn,1.0);
|
||||
|
||||
mo.add(1,3,-3,up,1.0);
|
||||
mo.add(1,3,-3,dn,1.0);
|
||||
mo.add(1,3,-2,up,1.0);
|
||||
mo.add(1,3,-2,dn,1.0);
|
||||
mo.add(1,3,-1,up,1.0);
|
||||
mo.add(1,3,-1,dn,1.0);
|
||||
mo.add(1,3, 0,up,1.0);
|
||||
mo.add(1,3, 0,dn,1.0);
|
||||
mo.add(1,3, 1,up,1.0);
|
||||
mo.add(1,3, 1,dn,1.0);
|
||||
mo.add(1,3, 2,up,1.0);
|
||||
mo.add(1,3, 2,dn,1.0);
|
||||
mo.add(1,3, 3,up,1.0);
|
||||
mo.add(1,3, 3,dn,1.0);
|
||||
|
||||
mo.add(2,1,-1,up,1.0);
|
||||
mo.add(2,1,-1,dn,1.0);
|
||||
mo.add(2,1, 0,up,1.0);
|
||||
mo.add(2,1, 0,dn,1.0);
|
||||
mo.add(2,1, 1,up,1.0);
|
||||
mo.add(2,1, 1,dn,1.0);
|
||||
|
||||
// cs[1] = 2;
|
||||
// cratio[1] = 0.3;
|
||||
// cs[2] = 10;
|
||||
// cratio[2] = 0.35;
|
||||
// cs[3]=18;
|
||||
// cratio[2] = 0.4;
|
||||
// cs[4] = 36;
|
||||
// cratio[4] = 0.45;
|
||||
// cs[5] = 54;
|
||||
// cratio[5] = 0.5;
|
||||
// cs[6] = 86;
|
||||
// cratio[6] = 0.55;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
##########################################################
|
||||
# OHMMS application makefile stub for suite: linuxicc
|
||||
# Created Sat Mar 29 15:39:36 CST 2003 by jnkim on bach
|
||||
# Generated by configure --arch linuxicc --tb
|
||||
##########################################################
|
||||
#include /home/common/Codes/Make.include
|
||||
|
||||
OHMMSDIR = $(HOME)/Projects/qmcPlusPlus
|
||||
HFDIR = $(HOME)/Projects/qmcPlusPlus
|
||||
ODIR = icc
|
||||
OHMMSARCH = ia32
|
||||
OHMMS_SRCDIR = $(OHMMSDIR)/src
|
||||
OHMMS_BINDIR = $(OHMMSDIR)/bin
|
||||
OHMMS_LIBDIR = $(OHMMSDIR)/lib
|
||||
OHMMS_LIBNAME = Ohmms-icc
|
||||
OHMMS_LIBEXT =
|
||||
OHMMS_LIBRARY = lib$(OHMMS_LIBNAME).$(OHMMS_LIBEXT)
|
||||
BLITZINC = -I/usr/apps/tools/blitz
|
||||
HDF5INC = -I/usr/local/include
|
||||
HDF5LIB = -lhdf5
|
||||
|
||||
### names of applications
|
||||
CXX = icc
|
||||
CC = icc
|
||||
F77 = ifc
|
||||
LD = icc
|
||||
LD_PARALLEL = 1
|
||||
|
||||
### flags for applications
|
||||
CXXOPTFLAGS = -DADD_ -O3 -restrict -unroll
|
||||
CXXDEBUGFLAGS = -DADD_ -g -restrict
|
||||
|
||||
CCOPTFLAGS = -DADD_ -O3 -restrict -unroll
|
||||
CCDEBUGFLAGS = -DADD_ -g -restrict
|
||||
|
||||
F77OPTFLAGS = -fpp2 -O3
|
||||
F77DEBUGFLAGS = -fpp2 -g
|
||||
|
||||
OHMMSINC = -I$(HFDIR)/src -I/usr/include/libxml2 -I/usr/local/include $(BLITZINC) $(HDF5INC)
|
||||
|
||||
#OHMMSDEF = -DOHMMS_DIM=3 -DENABLE_TB -DENABLE_LIBXML2 -DUSE_BLITZ
|
||||
OHMMSDEF = -DOHMMS_DIM=3 -DENABLE_TB -DENABLE_LIBXML2 -MMD -DPRINT_DEBUG -DUSE_HDF5
|
||||
OHMMSLIBS = -lxml2 $(BLITZLIB) $(HDF5LIB)
|
||||
|
||||
#CXXFLAGSAPP = $(OHMMSDEF) $(CXXOPTFLAGS)
|
||||
#CXXLDFLAGS = $(OHMMSDEF) $(CXXOPTFLAGS)
|
||||
CXXFLAGSAPP = $(OHMMSDEF) $(CXXDEBUGFLAGS)
|
||||
CXXLDFLAGS = $(OHMMSDEF) $(CXXDEBUGFLAGS)
|
||||
F77FLAGS = $(F77OPTFLAGS)
|
||||
AR = icc cr
|
||||
|
||||
F77AR = ar cr
|
||||
RANLIB = ranlib
|
||||
##########################################################
|
||||
# End of user makefile stub file lib/makefile.linuxicc
|
||||
##########################################################
|
|
@ -0,0 +1,71 @@
|
|||
#CONFIGURE_FILE(${qmcPlusPlus_SOURCE_DIR}/src/Configuration.h.in
|
||||
# ${qmcPlusPlus_BINARY_DIR}/src/Configuration.h)
|
||||
CONFIGURE_FILE(${qmcPlusPlus_SOURCE_DIR}/src/ohmms-config.h.cmake.in
|
||||
${qmcPlusPlus_BINARY_DIR}/src/ohmms-config.h)
|
||||
|
||||
SET(UTILITIES
|
||||
Utilities/RandRandom.cpp
|
||||
Utilities/RandomGenerator.cpp
|
||||
Utilities/OhmmsObject.cpp
|
||||
Utilities/SpeciesSet.cpp
|
||||
Utilities/SimpleParser.cpp
|
||||
Utilities/OhmmsInform.cpp
|
||||
Utilities/OhmmsInfo.cpp
|
||||
OhmmsApp/ProjectData.cpp
|
||||
OhmmsApp/RandomNumberControl.cpp
|
||||
Platforms/sysutil.cpp
|
||||
)
|
||||
|
||||
SET(PARTICLE
|
||||
Particle/ParticleSet.cpp
|
||||
Particle/MCWalkerConfiguration.cpp
|
||||
Particle/DistanceTable.cpp
|
||||
Particle/HDFWalkerIO.cpp
|
||||
)
|
||||
|
||||
SET(PARTICLEIO
|
||||
ParticleTags.cpp
|
||||
ParticleIO/ParticleLayoutIO.cpp
|
||||
ParticleIO/XMLParticleIO.cpp
|
||||
ParticleIO/HDFParticleIO.cpp
|
||||
)
|
||||
|
||||
|
||||
SET(MESSAGE
|
||||
Message/Communicate.cpp
|
||||
)
|
||||
|
||||
SET(OPTIMIZE
|
||||
Optimize/Minimize.cpp
|
||||
)
|
||||
|
||||
SET(HAMILTONIAN
|
||||
QMCHamiltonians/QMCHamiltonianBase.cpp
|
||||
QMCHamiltonians/LocalPPotential.cpp
|
||||
)
|
||||
|
||||
SET(WFSBASE
|
||||
QMCWaveFunctions/JastrowBuilder.cpp
|
||||
QMCWaveFunctions/TrialWaveFunction.cpp
|
||||
)
|
||||
|
||||
#Only basic packages common for both AtomicHF and QMC
|
||||
SET(BASEDIR
|
||||
${UTILITIES}
|
||||
${MESSAGE}
|
||||
)
|
||||
ADD_LIBRARY(qmcbase ${BASEDIR})
|
||||
|
||||
#QMC-related package, build qmc
|
||||
SET(QMCBASEDIR
|
||||
${PARTICLE}
|
||||
${PARTICLEIO}
|
||||
${OPTIMIZE}
|
||||
${HAMILTONIAN}
|
||||
${WFSBASE}
|
||||
)
|
||||
|
||||
#SUBDIRS(SQD)
|
||||
ADD_LIBRARY(qmc ${QMCBASEDIR})
|
||||
SUBDIRS(QMC)
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_QMC_TRAITS_H
|
||||
#define OHMMS_QMC_TRAITS_H
|
||||
|
||||
#include "ohmms-config.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include "OhmmsPETE/Tensor.h"
|
||||
#include "OhmmsData/OhmmsElementBase.h"
|
||||
#include "Lattice/UniformGridLayout.h"
|
||||
#include "ParticleBase/ParticleAttrib.h"
|
||||
#include "ParticleBase/ParticleBase.h"
|
||||
|
||||
namespace ohmmsqmc {
|
||||
|
||||
/** traits for the common particle attributes
|
||||
*
|
||||
*This is an alternative to the global typedefs.
|
||||
*/
|
||||
struct PtclAttribTraits {
|
||||
|
||||
typedef int Index_t;
|
||||
typedef ParticleAttrib<Index_t> ParticleIndex_t;
|
||||
typedef ParticleAttrib<OHMMS_PRECISION> ParticleScalar_t;
|
||||
typedef ParticleAttrib<TinyVector<OHMMS_PRECISION, OHMMS_DIM> > ParticlePos_t;
|
||||
typedef ParticleAttrib<Tensor<OHMMS_PRECISION, OHMMS_DIM> > ParticleTensor_t;
|
||||
|
||||
};
|
||||
|
||||
/** traits for QMC variables
|
||||
*
|
||||
*typedefs for the QMC data types
|
||||
*/
|
||||
struct QMCTraits {
|
||||
enum {DIM = OHMMS_DIM};
|
||||
typedef OHMMS_INDEXTYPE IndexType;
|
||||
typedef OHMMS_PRECISION RealType;
|
||||
typedef OHMMS_PRECISION ValueType;
|
||||
typedef TinyVector<RealType,DIM> PosType;
|
||||
typedef TinyVector<ValueType,DIM> GradType;
|
||||
};
|
||||
|
||||
/** Particle traits to use UniformGridLayout for the ParticleLayout.
|
||||
*/
|
||||
struct PtclOnLatticeTraits {
|
||||
|
||||
typedef UniformGridLayout<OHMMS_PRECISION,OHMMS_DIM> ParticleLayout_t;
|
||||
|
||||
typedef int Index_t;
|
||||
typedef ParticleLayout_t::Scalar_t Scalar_t;
|
||||
typedef ParticleLayout_t::SingleParticleIndex_t SingleParticleIndex_t;
|
||||
typedef ParticleLayout_t::SingleParticlePos_t SingleParticlePos_t;
|
||||
typedef ParticleLayout_t::Tensor_t Tensor_t;
|
||||
|
||||
typedef ParticleAttrib<Index_t> ParticleIndex_t;
|
||||
typedef ParticleAttrib<Scalar_t> ParticleScalar_t;
|
||||
typedef ParticleAttrib<SingleParticlePos_t> ParticlePos_t;
|
||||
typedef ParticleAttrib<Tensor_t> ParticleTensor_t;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,208 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_QMC_LOCALENERGYESTIMATOR_H
|
||||
#define OHMMS_QMC_LOCALENERGYESTIMATOR_H
|
||||
#include <fstream>
|
||||
#include "OhmmsData/libxmldefs.h"
|
||||
#include "Estimators/ScalarEstimatorBase.h"
|
||||
|
||||
namespace ohmmsqmc {
|
||||
|
||||
/*** A class to evaluate the local energy
|
||||
*
|
||||
*The LocalEnergyEstimator evaluates
|
||||
<ul>
|
||||
<li> LocalEnergy
|
||||
<li> Variance of the LocalEnergy
|
||||
</ul>
|
||||
and the values of each QHCHamiltonianBase elements added by an application.
|
||||
Typical local energies are
|
||||
<li> Kinetic Energy
|
||||
<li> External Potential Energy
|
||||
<li> Electron-Electron Energy
|
||||
<li> Ion-Ion Energy (for molecules only)
|
||||
<li> Conserved Quantity (VMC only)
|
||||
</ul>
|
||||
The method of evaluating the estimators is as follows
|
||||
\f[
|
||||
\langle O \rangle = \frac{\sum_{i=1}^N w_i O_i}{\sum_{i=1}^N w_i}
|
||||
\f]
|
||||
where the sum runs over the total number of accumulated walkers
|
||||
and \f$ w_i \f$ is the weight of the \f$ ith \f$ walker.
|
||||
*
|
||||
*The formula for the LocalEnergy
|
||||
\f[ E_L({\bf R}) = \frac{\hat{H} \Psi({\bf R})}{ \Psi({\bf R})} \f]
|
||||
*/
|
||||
template<class T>
|
||||
class LocalEnergyEstimator: public ScalarEstimatorBase<T> {
|
||||
|
||||
///locator of the first data this object handles
|
||||
int LocalEnergyIndex;
|
||||
|
||||
///local data
|
||||
T energy_sum, energy_sq_sum;
|
||||
///vector to contain the names of all the constituents of the local energy
|
||||
std::vector<string> elocal_name;
|
||||
///vector to contain all the constituents of the local energy
|
||||
std::vector<T> elocal;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename ScalarEstimatorBase<T>::Walker_t Walker_t;
|
||||
|
||||
LocalEnergyEstimator(QMCHamiltonian& h):energy_sum(0.0),
|
||||
energy_sq_sum(0.0) {
|
||||
int nterms=h.size();
|
||||
elocal.resize(nterms);
|
||||
elocal_name.resize(nterms+2);
|
||||
elocal_name[0] = "LocalEnergy";
|
||||
elocal_name[1] = "Variance";
|
||||
int ii=2;
|
||||
for(int i=0; i < nterms; i++, ii++) elocal_name[ii] = h.getName(i);
|
||||
}
|
||||
|
||||
/**
|
||||
@param record a container class for storing scalar records (name,value)
|
||||
@brief add the local energy, variance and all the constituents
|
||||
of the local energy to the scalar record container
|
||||
*/
|
||||
void add2Record(RecordNamedProperty<T>& record) {
|
||||
LocalEnergyIndex = record.add(elocal_name[0].c_str());
|
||||
for(int i=1; i<elocal_name.size(); i++)
|
||||
record.add(elocal_name[i].c_str());
|
||||
}
|
||||
|
||||
inline void accumulate(const Walker_t& awalker, T wgt) {
|
||||
T e = awalker.Properties(LocalEnergy);
|
||||
energy_sum += wgt*e; energy_sq_sum += wgt*e*e;
|
||||
for(int i=0, ii=0; i<elocal.size(); i++) {
|
||||
elocal[i] += wgt*(awalker.E[i]);
|
||||
}
|
||||
}
|
||||
|
||||
///reset all the cumulative sums to zero
|
||||
inline void reset() {
|
||||
energy_sum = T(); energy_sq_sum = T();
|
||||
for(int i=0; i<elocal.size(); i++) {
|
||||
elocal[i] = T();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
*\param record a container class for storing scalar records (name,value)
|
||||
*\param wgtinv the inverse weight
|
||||
*\brief calculate the averages and reset to zero
|
||||
*/
|
||||
inline void report(RecordNamedProperty<T>& record, T wgtinv) {
|
||||
b_average = energy_sum*wgtinv;
|
||||
b_variance = energy_sq_sum*wgtinv-b_average*b_average;
|
||||
register int ir=LocalEnergyIndex;
|
||||
record[ir++] = b_average;
|
||||
record[ir++] = b_variance;
|
||||
for(int i=0; i<elocal.size(); i++) {
|
||||
record[ir++] = elocal[i]*wgtinv;
|
||||
elocal[i] = T();
|
||||
}
|
||||
energy_sum = T(); energy_sq_sum = T();
|
||||
}
|
||||
};
|
||||
|
||||
// template<class T>
|
||||
// class LocalEnergyEstimator: public EstimatorBase<T> {
|
||||
|
||||
// std::string RootName;
|
||||
// std::ofstream fout;
|
||||
// std::vector<std::string> elocal_name;
|
||||
// std::vector<T> elocal;
|
||||
// public:
|
||||
|
||||
// LocalEnergyEstimator(QMCHamiltonian& h) {
|
||||
// int nterms=h.size();
|
||||
// elocal.resize(nterms);
|
||||
// elocal_name.resize(nterms+2);
|
||||
// elocal_name[0] = "LocalEnergy";
|
||||
// elocal_name[1] = "Variance";
|
||||
// int ii=2;
|
||||
// for(int i=0; i < nterms; i++, ii++) elocal_name[ii] = h.getName(i);
|
||||
// }
|
||||
|
||||
// inline void resetReportSettings(const string& aname) {
|
||||
// if(RootName != aname) {
|
||||
// finalize();
|
||||
// }
|
||||
// RootName = aname;
|
||||
// string fname(aname);
|
||||
// fname.append(".e.dat");
|
||||
// fout.open(fname.c_str());
|
||||
// fout.setf(ios::right,ios::scientific);
|
||||
// fout << "# index ";
|
||||
// for(int i=0; i < elocal_name.size(); i++)
|
||||
// fout << setw(14) << elocal_name[i];
|
||||
// fout << endl;
|
||||
// fout<<setprecision(8);
|
||||
// }
|
||||
|
||||
// inline void finalize() {
|
||||
// if(fout.is_open()) fout.close();
|
||||
// }
|
||||
|
||||
// inline void accumulate(const MCWalkerConfiguration& W) {
|
||||
|
||||
// for(MCWalkerConfiguration::const_iterator it = W.begin();
|
||||
// it != W.end(); it++){
|
||||
// T w = (*it)->Properties(Weight);
|
||||
// for(int i=0; i<elocal.size(); i++) {
|
||||
// elocal[i] += w*((*it)->E[i]);
|
||||
// }
|
||||
// add(w,(*it)->Properties(LocalEnergy));
|
||||
// }
|
||||
// }
|
||||
|
||||
// inline void report(int iter){
|
||||
// if(iter%stride == 0) {
|
||||
// register T winv = 1.0/d_v[WEIGHT];
|
||||
// register T eavg = d_v[VALUE]*winv;
|
||||
// register T evar = d_v[VALUE_SQ]*winv-eavg*eavg;
|
||||
|
||||
// fout << setw(10) << iter;
|
||||
// fout << setw(15) << eavg << setw(15) << evar;
|
||||
// for(int i=0; i<elocal.size(); i++) {
|
||||
// fout << setw(15) << elocal[i]*winv; elocal[i]=0.0;
|
||||
// }
|
||||
// fout << endl;
|
||||
|
||||
// d_v =0.0;
|
||||
// d_v[AVERAGE]=eavg;
|
||||
// d_v[VARIANCE]=evar;
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool get(ostream& os) const {return true;}
|
||||
// bool put(istream& is) {return true;}
|
||||
// bool put(xmlNodePtr cur) {return true;}
|
||||
|
||||
// };
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,83 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2004- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_QMC_SCALAR_ESTIMATORBASE_H
|
||||
#define OHMMS_QMC_SCALAR_ESTIMATORBASE_H
|
||||
#include "Configuration.h"
|
||||
#include "OhmmsData/RecordProperty.h"
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include "Particle/MCWalkerConfiguration.h"
|
||||
|
||||
namespace ohmmsqmc {
|
||||
|
||||
/** Abstract class for an estimator of an operator.
|
||||
*
|
||||
*@note derived classes should provide virtual functions of
|
||||
ScalarEstimatorBase
|
||||
*
|
||||
* void add2Record(RecordNameProperty<T>& record);
|
||||
*
|
||||
* void accumulate(const MCWalkerConfiguration&);
|
||||
*
|
||||
* void report(RecordNameProperty<T>& record);
|
||||
*/
|
||||
template<class T>
|
||||
struct ScalarEstimatorBase {
|
||||
|
||||
typedef typename MCWalkerConfiguration::Walker_t Walker_t;
|
||||
T b_average;
|
||||
T b_variance;
|
||||
|
||||
ScalarEstimatorBase():b_average(T()), b_variance(T()){}
|
||||
|
||||
inline T average() const { return b_average;}
|
||||
inline T variance() const { return b_variance;}
|
||||
|
||||
/** add the content of the scalar estimator to the record
|
||||
*\param record scalar data list
|
||||
*
|
||||
*Each ScalarEstimatorBase object adds a number of scalar data to record.
|
||||
*/
|
||||
virtual void add2Record(RecordNamedProperty<T>& record) = 0;
|
||||
|
||||
/** a virtual function to accumulate expectation values
|
||||
*\param awalker a single walker
|
||||
*\param wgt the weight
|
||||
*/
|
||||
virtual void accumulate(const Walker_t& awalker, T wgt) = 0;
|
||||
|
||||
|
||||
/** a virtual function to report the scalar estimator
|
||||
*@param record
|
||||
*
|
||||
*Evalaute the block-average and flush the internal data for new averages
|
||||
*/
|
||||
virtual void report(RecordNamedProperty<T>& record, T wgtinv) = 0;
|
||||
|
||||
/// a virtual function to flush the internal data to start a new block average
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,197 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#include "Particle/MCWalkerConfiguration.h"
|
||||
#include "QMCHamiltonians/QMCHamiltonianBase.h"
|
||||
#include "Estimators/ScalarEstimatorManager.h"
|
||||
#include "Estimators/LocalEnergyEstimator.h"
|
||||
|
||||
using namespace ohmmsqmc;
|
||||
|
||||
ScalarEstimatorManager::ScalarEstimatorManager(QMCHamiltonian& h):
|
||||
Stride(1000), WeightSum(0.0), H(h), RootName("estimator"),
|
||||
OutStream(NULL) { }
|
||||
|
||||
ScalarEstimatorManager::~ScalarEstimatorManager(){
|
||||
Estimators.erase(Estimators.begin(), Estimators.end());
|
||||
if(OutStream) delete OutStream;
|
||||
}
|
||||
|
||||
int
|
||||
ScalarEstimatorManager::add(EstimatorType* newestimator, const string& aname) {
|
||||
|
||||
std::map<string,int>::iterator it = EstimatorMap.find(aname);
|
||||
if(it == EstimatorMap.end()) {
|
||||
int n = Estimators.size();
|
||||
Estimators.push_back(newestimator);
|
||||
EstimatorMap[aname] = n;
|
||||
//newestimator->add2Record(BlockAverages);
|
||||
return n;
|
||||
} else {
|
||||
cout << "Already added estimator " << aname << endl;
|
||||
return (*it).second;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief reset the internal data of all the estimators for new averages
|
||||
*/
|
||||
void
|
||||
ScalarEstimatorManager::reset() {
|
||||
WeightSum = 0.0;
|
||||
for(int i=0; i< Estimators.size(); i++) Estimators[i]->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief accumulate data for all the estimators
|
||||
*/
|
||||
void
|
||||
ScalarEstimatorManager::accumulate(const MCWalkerConfiguration& W) {
|
||||
|
||||
for(MCWalkerConfiguration::const_iterator it = W.begin();
|
||||
it != W.end(); it++){
|
||||
RealType wgt = (*it)->Properties(Weight);
|
||||
WeightSum += wgt;
|
||||
for(int i=0; i< Estimators.size(); i++)
|
||||
Estimators[i]->accumulate(**it,wgt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief compute the averages for all the estimators and reset
|
||||
*/
|
||||
void ScalarEstimatorManager::flush(){
|
||||
RealType wgtinv = 1.0/WeightSum;
|
||||
for(int i=0; i<Estimators.size(); i++)
|
||||
Estimators[i]->report(BlockAverages,wgtinv);
|
||||
|
||||
BlockAverages[WeightIndex] = WeightSum;
|
||||
WeightSum = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
@param iter the interval
|
||||
@brief print the averages for all the estimators to a file
|
||||
*/
|
||||
void ScalarEstimatorManager::report(int iter){
|
||||
if(iter%Stride == 0) {
|
||||
(*OutStream) << setw(10) << iter;
|
||||
for(int i=0; i<BlockAverages.size();i++)
|
||||
(*OutStream) << setw(16) << BlockAverages[i];
|
||||
(*OutStream) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param iter the interval
|
||||
@brief combines the functionality of flush and report
|
||||
*/
|
||||
void ScalarEstimatorManager::flushreport(int iter){
|
||||
if(iter%Stride == 0) {
|
||||
RealType wgtinv = 1.0/WeightSum;
|
||||
for(int i=0; i<Estimators.size(); i++)
|
||||
Estimators[i]->report(BlockAverages,wgtinv);
|
||||
|
||||
BlockAverages[WeightIndex] = WeightSum;
|
||||
WeightSum = 0.0;
|
||||
(*OutStream) << setw(10) << iter;
|
||||
for(int i=0; i<BlockAverages.size();i++)
|
||||
(*OutStream) << setw(16) << BlockAverages[i];
|
||||
(*OutStream) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScalarEstimatorManager::resetReportSettings(const string& aname) {
|
||||
|
||||
//at least have local energy
|
||||
if(Estimators.empty()) {
|
||||
add(new LocalEnergyEstimator<RealType>(H),"elocal");
|
||||
}
|
||||
|
||||
//update the weight index
|
||||
for(int i=0; i<Estimators.size(); i++)
|
||||
Estimators[i]->add2Record(BlockAverages);
|
||||
WeightIndex = BlockAverages.add("WeightSum");
|
||||
if(aname != RootName) {
|
||||
RootName = aname;
|
||||
string fname(aname);
|
||||
fname.append(".scalar.dat");
|
||||
if(OutStream) delete OutStream;
|
||||
OutStream = new ofstream(fname.c_str());
|
||||
OutStream->setf(ios::scientific, ios::floatfield);
|
||||
OutStream->setf(ios::left,ios::adjustfield);
|
||||
}
|
||||
|
||||
for(int i=0; i<BlockAverages.size();i++) BlockAverages[i] = 0.0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@brief print the header to the output file
|
||||
*/
|
||||
void
|
||||
ScalarEstimatorManager::reportHeader() {
|
||||
*OutStream << "# index ";
|
||||
for(int i=0; i<BlockAverages.size(); i++)
|
||||
(*OutStream) << setw(16) << BlockAverages.Name[i];
|
||||
(*OutStream) << endl;
|
||||
OutStream->setf(ios::right,ios::adjustfield);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief closes the stream to the output file
|
||||
*/
|
||||
void
|
||||
ScalarEstimatorManager::finalize() {
|
||||
if(OutStream) delete OutStream;
|
||||
OutStream = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@param istride an inverval of reportting/flushing the cummulative quantities
|
||||
@brief set the stride of all the estimators to istride
|
||||
*/
|
||||
void
|
||||
ScalarEstimatorManager::setStride(int istride) {
|
||||
Stride = istride;
|
||||
}
|
||||
|
||||
ScalarEstimatorManager::EstimatorType*
|
||||
ScalarEstimatorManager::getEstimator(const string& a) {
|
||||
std::map<string,int>::iterator it = EstimatorMap.find(a);
|
||||
if(it == EstimatorMap.end()) {
|
||||
return NULL;
|
||||
} else {
|
||||
return Estimators[(*it).second];
|
||||
}
|
||||
}
|
||||
|
||||
bool ScalarEstimatorManager::put(xmlNodePtr cur) {
|
||||
|
||||
//if(Estimators.empty()) {
|
||||
// add(new LocalEnergyEstimator<RealType>(H),"elocal");
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,107 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim and Jordan Vincent
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_QMC_SCALAR_ESTIMATORMANAGER_H
|
||||
#define OHMMS_QMC_SCALAR_ESTIMATORMANAGER_H
|
||||
|
||||
#include "Configuration.h"
|
||||
#include "Estimators/ScalarEstimatorBase.h"
|
||||
|
||||
namespace ohmmsqmc {
|
||||
|
||||
class MCWalkerConifugration;
|
||||
class QMCHamiltonian;
|
||||
|
||||
/**Class to manage a set of ScalarEstimators */
|
||||
class ScalarEstimatorManager: public QMCTraits {
|
||||
|
||||
public:
|
||||
|
||||
typedef ScalarEstimatorBase<RealType> EstimatorType;
|
||||
|
||||
ScalarEstimatorManager(QMCHamiltonian& h);
|
||||
~ScalarEstimatorManager();
|
||||
|
||||
///return the number of ScalarEstimators
|
||||
inline int size() const { return Estimators.size();}
|
||||
|
||||
///process xml tag associated with estimators
|
||||
bool put(xmlNodePtr cur);
|
||||
|
||||
void accumulate(const MCWalkerConfiguration& W);
|
||||
void resetReportSettings(const string& aname);
|
||||
void reportHeader();
|
||||
void flushreport(int iter);
|
||||
void report(int iter);
|
||||
void flush();
|
||||
void finalize();
|
||||
void reset();
|
||||
|
||||
/*!\return the index of the named column
|
||||
*\brief add a column with the name
|
||||
*/
|
||||
inline int addColumn(const char* aname) {
|
||||
return BlockAverages.add(aname);
|
||||
}
|
||||
|
||||
///add the value of the i-th column with a value v
|
||||
inline void setColumn(int i, RealType v) {
|
||||
BlockAverages[i] = v;
|
||||
}
|
||||
|
||||
/*!\return the index of the newestimator
|
||||
*\brief add a new estimator with name aname
|
||||
*/
|
||||
int add(EstimatorType* newestimator, const string& aname);
|
||||
|
||||
///set the stride for all the estimators
|
||||
void setStride(int istride);
|
||||
|
||||
///return a pointer to the estimator aname
|
||||
EstimatorType* getEstimator(const string& a);
|
||||
|
||||
///return the average for estimator i
|
||||
inline RealType average(int i) const {
|
||||
return Estimators[i]->average();
|
||||
}
|
||||
|
||||
///returns a variance for estimator i
|
||||
inline RealType variance(int i) const {
|
||||
return Estimators[i]->variance();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
string RootName;
|
||||
int Stride;
|
||||
int WeightIndex;
|
||||
ostream* OutStream;
|
||||
RealType WeightSum;
|
||||
QMCHamiltonian& H;
|
||||
RecordNamedProperty<RealType> BlockAverages;
|
||||
std::map<string,int> EstimatorMap;
|
||||
vector<EstimatorType*> Estimators;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,251 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
/**@file CrystalLattice.cpp
|
||||
*@brief Member function definitions of CrystalLattice<T,D>, included by CrystalLattice.h
|
||||
*/
|
||||
#include "Lattice/MakeCrystalLattice.h"
|
||||
|
||||
/*! \fn CrystalLattice::CrystalLattice()
|
||||
* Default constructor. Initialized to a \p 1x1x1 cubic supercell.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
CrystalLattice<T,D>::CrystalLattice() {
|
||||
R.diagonal(1e10);
|
||||
G = R;
|
||||
M = R;
|
||||
Volume = 1;
|
||||
for(int i=0; i<D; i++) BoxBConds[i] = 1;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned D>
|
||||
CrystalLattice<T,D>::CrystalLattice(const CrystalLattice<T,D>& rhs) {
|
||||
|
||||
R = rhs.R;
|
||||
BConds = rhs.BConds;
|
||||
for(int idir=0; idir<D; idir++) {
|
||||
BoxBConds[idir] = rhs.BoxBConds[idir];//!< Bonundary Condition
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::set(int argc, char **argv) {
|
||||
vector<string> opt;
|
||||
for(int i=0; i<argc; i++) opt.push_back(argv[i]);
|
||||
set(opt);
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::set(vector<string>& argv) {
|
||||
makelattice<CrystalLattice<T,D> >::apply(*this, argv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::set(const Tensor<T,D>& lat) {
|
||||
R = lat;
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::set(T sc, T* lat) {
|
||||
if(lat) {
|
||||
int ii=0;
|
||||
for(int i=0; i<D; i++)
|
||||
for(int j=0; j<D; j++)
|
||||
R(i,j) = lat[ii++];
|
||||
|
||||
R *= sc;
|
||||
} else {
|
||||
R = 0.0e0;
|
||||
R.diagonal(sc);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void
|
||||
CrystalLattice<T,D>::set(const CrystalLattice<T,D>& oldlat, int *uc) {
|
||||
R = oldlat.R;
|
||||
BConds = oldlat.BConds;
|
||||
for(int idir=0; idir<D; idir++) {
|
||||
BoxBConds[idir] = oldlat.BoxBConds[idir];//!< Bonundary Condition
|
||||
}
|
||||
if(uc) {
|
||||
for(int i=0; i<D; i++)
|
||||
for(int j=0; j<D; j++) R(i,j) *= static_cast<T>(uc[i]);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::reset() {
|
||||
|
||||
G = inverse(R); //G = transpose(Inverse(R));
|
||||
Volume = fabs(det(R));
|
||||
//M = dot(transpose(R),R);
|
||||
M = dot(R,transpose(R));
|
||||
T t = pow(TWOPI,2.0);
|
||||
Mg = t*dot(transpose(G),G);
|
||||
for(int i=0; i<D; i++)
|
||||
for(int j=0; j<D; j++)
|
||||
Rv[i][j] = R(i,j);
|
||||
for(int i=0; i<D; i++)
|
||||
for(int j=0; j<D; j++)
|
||||
Gv[i][j] = G(j,i);
|
||||
}
|
||||
|
||||
/*! \fn CrystalLattice<T,D>::operator=(const CrystalLattice<T,D>& rhs)
|
||||
* \param rhs a CrystalLattice to be copied
|
||||
* \brief Copy all the properties of the lattice,
|
||||
* including boundary conditions and grid paritions.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
CrystalLattice<T,D>&
|
||||
CrystalLattice<T,D>::operator=(const CrystalLattice<T,D>& rhs) {
|
||||
|
||||
R = rhs.R;
|
||||
BConds = rhs.BConds;
|
||||
for(int idir=0; idir<D; idir++) {
|
||||
BoxBConds[idir] = rhs.BoxBConds[idir];//!< Bonundary Condition
|
||||
}
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! \fn CrystalLattice<T,D>::operator=(const Tensor<T,D>& rhs)
|
||||
* \param rhs a Tensor to be copied
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
CrystalLattice<T,D>&
|
||||
CrystalLattice<T,D>::operator=(const Tensor<T,D>& rhs) {
|
||||
R = rhs;
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! \fn CrystalLattice<T,D>::operator*=(T sc)
|
||||
* \param sc A scaling factor.
|
||||
* \brief Rescale this supercell by a scalar.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
CrystalLattice<T,D>&
|
||||
CrystalLattice<T,D>::operator*=(T sc) {
|
||||
R *= sc;
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void CrystalLattice<T,D>::print(ostream& os, int level) const {
|
||||
|
||||
/*\note level == 0: print only the lattice vectors
|
||||
* level == 1: lattice vectors, boundary conditions, grid
|
||||
* level == 2: + all the internal values
|
||||
*/
|
||||
|
||||
os << "<lattice>" << endl;
|
||||
for(int i=0; i<D; i++) {
|
||||
os << Rv[i] << endl;
|
||||
}
|
||||
os << "</lattice>" << endl;
|
||||
|
||||
if(level > 0) {
|
||||
os << "<bconds> ";
|
||||
for(int i=0; i<D; i++) {
|
||||
if(BoxBConds[i]) os << " p ";
|
||||
else os << " n ";
|
||||
}
|
||||
os << " </bconds>" << endl;
|
||||
}
|
||||
|
||||
if(level > 1) {
|
||||
os << "Volume (A^3) = " << Volume << endl;
|
||||
os << "Reciprocal vectors without 2*pi.\n";
|
||||
for(int i=0; i<D; i++) {
|
||||
os << "g_"<< i+1<< " = " << Gv[i] << endl;
|
||||
}
|
||||
os << "Metric tensor in real-space.\n";
|
||||
for(int i=0; i<D; i++) {
|
||||
os << "h_"<< i+1<< " = ";
|
||||
for(int j=0; j< D; j++) {
|
||||
os << M(i,j) << " ";
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
os << "Metric tensor in g-space.\n";
|
||||
for(int i=0; i<D; i++) {
|
||||
os << "h_"<< i+1<< " = ";
|
||||
for(int j=0; j< D; j++) {
|
||||
os << Mg(i,j) << " ";
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned D>
|
||||
inline bool operator==(const CrystalLattice<T,D>& lhs,
|
||||
const CrystalLattice<T,D>& rhs) {
|
||||
const double eps = 1e-6;
|
||||
for(int i=0; i<D*D; i++)
|
||||
if(abs(lhs.R[i]-rhs.R[i]) > eps) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
inline bool operator!=(const CrystalLattice<T,D>& lhs,
|
||||
const CrystalLattice<T,D>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
// free function to check if a CrystalLattice is orthorhombic
|
||||
template<class T, unsigned D>
|
||||
inline bool orthorombic(const CrystalLattice<T,D>& a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//!< Returns true if the off-diagonal elements of Rm are zero.
|
||||
template<class T>
|
||||
bool orthorombic(const CrystalLattice<T,2>& a, T) {
|
||||
const T eps = 1e-6;
|
||||
return ((a.R(0,1) < eps) && (a.R(1,0) < eps));
|
||||
}
|
||||
|
||||
//!< Returns true if the off-diagonal elements of Rm are zero.
|
||||
template<class T>
|
||||
bool orthorombic(const CrystalLattice<T,3>& a, T) {
|
||||
const T eps = 1e-6;
|
||||
return ((a.R(0,1) < eps) && (a.R(0,2) < eps) &&
|
||||
(a.R(1,0) < eps) && (a.R(1,2) < eps) &&
|
||||
(a.R(2,0) < eps) && (a.R(2,1) < eps) );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_CRYSTALLATTICE_H
|
||||
#define OHMMS_CRYSTALLATTICE_H
|
||||
#include <math.h>
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include "OhmmsPETE/Tensor.h"
|
||||
#include "Lattice/ParticleBConds.h"
|
||||
|
||||
/**@file CrystalLattice.h
|
||||
*@brief Declaration of CrystalLattice<T,D>
|
||||
*/
|
||||
|
||||
#ifndef TWOPI
|
||||
#ifndef M_PI
|
||||
#define TWOPI 6.3661977236758134308E-1
|
||||
#else
|
||||
#define TWOPI 2*M_PI
|
||||
#endif /* M_PI */
|
||||
#endif /* TWOPI */
|
||||
|
||||
/** class to assist copy and unit conversion operations on position vectors
|
||||
*/
|
||||
struct PosUnit {
|
||||
|
||||
/** enumeraton for the unit of position types.
|
||||
*/
|
||||
enum {CartesianUnit=0,/*!< indicates that the values are in Cartesian units*/
|
||||
LatticeUnit/*!< indicates that the values are in Lattice units*/
|
||||
};
|
||||
};
|
||||
|
||||
/** a class that defines a supercell in D-dimensional Euclean space.
|
||||
*
|
||||
*CrystalLattice handles the physical properties of a supercell, such
|
||||
*as lattice vectors, reciprocal vectors and metric tensors and provides
|
||||
*interfaces to access the lattice properties and convert units of
|
||||
*position vectors or a single-particle position from Cartesian to
|
||||
*Lattice Unit vice versa.
|
||||
*
|
||||
*The indices for R, G and D are chosen to perform
|
||||
*expression template operations with variable-cell algorithms.
|
||||
*
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct CrystalLattice{
|
||||
|
||||
///enumeration for the dimension of the lattice
|
||||
enum {DIM = D};
|
||||
//@{
|
||||
///the type of scalar
|
||||
typedef T Scalar_t;
|
||||
///the type of a D-dimensional position vector
|
||||
typedef TinyVector<T,D> SingleParticlePos_t;
|
||||
///the type of a D-dimensional index vector
|
||||
typedef TinyVector<int,D> SingleParticleIndex_t;
|
||||
///the type of a D-dimensional Tensor
|
||||
typedef Tensor<T,D> Tensor_t;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**@brief Physcial properties of a supercell*/
|
||||
/// Volume of a supercell
|
||||
T Volume;
|
||||
///Real-space unit vectors. R(i,j) i=vector and j=x,y,z
|
||||
Tensor_t R;
|
||||
///Reciprocal unit vectors. G(j,i) i=vector and j=x,y,z
|
||||
Tensor_t G;
|
||||
///Metric tensor
|
||||
Tensor_t M;
|
||||
///Metric tensor for G vectors
|
||||
Tensor_t Mg;
|
||||
/**@brief Real-space unit vectors.
|
||||
*
|
||||
*Introduced to efficiently return one vector at a time.
|
||||
*Rv[i] is D-dim vector of the ith direction.
|
||||
*/
|
||||
TinyVector<SingleParticlePos_t,D> Rv;
|
||||
/**@brief Reciprocal unit vectors.
|
||||
*
|
||||
*Introduced to efficiently return one vector at a time.
|
||||
*Gv[i] is D-dim vector of the ith direction.
|
||||
*/
|
||||
TinyVector<SingleParticlePos_t,D> Gv;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**@brief Parameters defining boundary Conditions */
|
||||
///Functors that apply boundary conditions on the position vectors
|
||||
ParticleBConds<T,D> BConds;
|
||||
///The boundary condition in each direction.
|
||||
TinyVector<int,D> BoxBConds;
|
||||
//@}
|
||||
|
||||
///default constructor, assign a huge supercell
|
||||
CrystalLattice();
|
||||
/** copy constructor
|
||||
@param rhs An existing SC object is copied to this SC.
|
||||
*/
|
||||
CrystalLattice(const CrystalLattice<T,D>& rhs);
|
||||
|
||||
///destructor
|
||||
virtual ~CrystalLattice(){ }
|
||||
|
||||
/**@param i the index of the directional vector, \f$i\in [0,D)\f$
|
||||
*@return The lattice vector of the ith direction
|
||||
*@brief Provide interfaces familiar to fotran users
|
||||
*/
|
||||
inline SingleParticlePos_t a(int i) const {
|
||||
return Rv[i];
|
||||
}
|
||||
|
||||
/**@param i the index of the directional vector, \f$i\in [0,D)\f$
|
||||
*@return The reciprocal vector of the ith direction
|
||||
*@brief Provide interfaces familiar to fotran users
|
||||
*/
|
||||
inline SingleParticlePos_t b(int i) const {
|
||||
return Gv[i];
|
||||
}
|
||||
|
||||
/** Convert a cartesian vector to a unit vector.
|
||||
* Boundary conditions are not applied.
|
||||
*/
|
||||
inline SingleParticlePos_t toUnit(const SingleParticlePos_t &r) const {
|
||||
return dot(r,G);
|
||||
}
|
||||
|
||||
/** Convert a unit vector to a cartesian vector.
|
||||
* Boundary conditions are not applied.
|
||||
*/
|
||||
inline SingleParticlePos_t toCart(const SingleParticlePos_t &c) const {
|
||||
return dot(c,R);
|
||||
}
|
||||
|
||||
/** evaluate the cartesian distance
|
||||
*@param ra a vector in the supercell unit
|
||||
*@param rb a vector in the supercell unit
|
||||
*@return Cartesian distance with two vectors in SC unit
|
||||
*
|
||||
@note The distance between two cartesian vectors are handled
|
||||
*by dot function defined in OhmmsPETE/TinyVector.h
|
||||
*/
|
||||
inline T Dot(const SingleParticlePos_t &ra,
|
||||
const SingleParticlePos_t &rb) const {
|
||||
return dot(ra,dot(M,rb));
|
||||
}
|
||||
|
||||
/** conversion of a reciprocal-vector
|
||||
*@param kin an input reciprocal vector in the Reciprocal-vector unit
|
||||
*@return k(reciprocal vector) in cartesian unit
|
||||
*/
|
||||
inline SingleParticlePos_t k_cart(const SingleParticlePos_t& kin) const {
|
||||
return TWOPI*dot(G,kin);
|
||||
}
|
||||
|
||||
/** evaluate \f$k^2\f$
|
||||
*
|
||||
*@param kin an input reciprocal vector in reciprocal-vector unit
|
||||
*@return \f$k_{in}^2\f$
|
||||
*/
|
||||
inline T ksq(const SingleParticlePos_t& kin) const {
|
||||
return dot(kin,dot(Mg,kin));
|
||||
}
|
||||
|
||||
///assignment operator
|
||||
CrystalLattice<T,D>& operator=(const CrystalLattice<T,D>& rhs);
|
||||
|
||||
/** assignment operator
|
||||
*@param rhs a tensor representing a unit cell
|
||||
*/
|
||||
CrystalLattice<T,D>& operator=(const Tensor<T,D>& rhs);
|
||||
|
||||
/** scale the lattice vectors by sc. All the internal data are reset.
|
||||
*@param sc the scaling value
|
||||
*@return a new CrystalLattice
|
||||
*/
|
||||
CrystalLattice<T,D>& operator*=(T sc);
|
||||
|
||||
/** set the lattice vector from the command-line options
|
||||
*@param argc the number of arguments
|
||||
*@param argv the argument lists
|
||||
*
|
||||
*This function is to provide a simple interface for testing.
|
||||
*/
|
||||
void set(int argc, char **argv);
|
||||
|
||||
/** set the lattice vector from the command-line options stored in a vector
|
||||
*@param argv the argument lists
|
||||
*
|
||||
*This function is to provide a simple interface for testing.
|
||||
*/
|
||||
void set(vector<string>& argv);
|
||||
|
||||
/** set the lattice vector by an array containing DxD T
|
||||
*@param sc a scalar to scale the input lattice parameters
|
||||
*@param lat the starting address of DxD T-elements representing a supercell
|
||||
*/
|
||||
void set(T sc, T* lat= NULL);
|
||||
|
||||
/** set the lattice vector by a CrystalLattice and expand it by integers
|
||||
*@param oldlat An input supercell to be copied.
|
||||
*@param uc An array to expand a supercell.
|
||||
*/
|
||||
void set(const CrystalLattice<T,D>& oldlat, int* uc= NULL);
|
||||
|
||||
/** set the lattice vector from the command-line options
|
||||
*@param lat a tensor representing a supercell
|
||||
*/
|
||||
void set(const Tensor<T,D>& lat);
|
||||
|
||||
/** Evaluate the reciprocal vectors, volume and metric tensor
|
||||
*/
|
||||
void reset();
|
||||
|
||||
//@{
|
||||
/* Copy functions with unit conversion*/
|
||||
template<class PA> void convert(const PA& pin, PA& pout) const;
|
||||
template<class PA> void convert2Unit(const PA& pin, PA& pout) const;
|
||||
template<class PA> void convert2Cart(const PA& pin, PA& pout) const;
|
||||
template<class PA> void convert2Unit(PA& pout) const;
|
||||
template<class PA> void convert2Cart(PA& pout) const;
|
||||
//@}
|
||||
|
||||
template<class PA> void applyBC(const PA& pin, PA& pout, T del=1.e-6) const;
|
||||
template<class PA> void applyBC(PA& pos, T del=1.e-6) const;
|
||||
|
||||
//! Print out CrystalLattice Data
|
||||
void print(ostream& , int level=2) const;
|
||||
};
|
||||
|
||||
//including the definitions of the member functions
|
||||
#include "Lattice/CrystalLattice.cpp"
|
||||
|
||||
/** Copy operation pout = pin with the unit checking of the in/out vectors
|
||||
*
|
||||
*@param pin an input position array
|
||||
*@param pout an output position array
|
||||
*
|
||||
*@note The units of in/out vectors are conserved.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
inline void CrystalLattice<T,D>::convert(const PA& pin, PA& pout) const
|
||||
{
|
||||
if(pin.getUnit() == pout.getUnit()) {
|
||||
pout = pin;
|
||||
return;
|
||||
}
|
||||
if(pin.getUnit() == PosUnit::LatticeUnit) {
|
||||
//convert to CartesianUnit
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = dot(pin[i],R);
|
||||
} else {
|
||||
//convert to LatticeUnit
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = dot(pin[i],G);
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy operation pout = pin with the unit checking of the in/out vectors
|
||||
*
|
||||
*@param pin an input position array
|
||||
*@param pout an output position array
|
||||
*
|
||||
*@note The unit of the out vector is forced to be Cartesian.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
inline void CrystalLattice<T,D>::convert2Cart(const PA& pin, PA& pout) const
|
||||
{
|
||||
pout.setUnit(PosUnit::CartesianUnit);
|
||||
if(pin.getUnit() == PosUnit::CartesianUnit)
|
||||
pout = pin;
|
||||
else //need to convert to CartesianUnit
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = dot(pin[i],R);
|
||||
}
|
||||
|
||||
/** Copy operation pout = pin with the unit checking of the in/out vectors
|
||||
*
|
||||
*@param pin an input position array
|
||||
*@param pout an output position array
|
||||
*
|
||||
*@note The unit of the out vector is forced to be Lattice unit.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
inline void CrystalLattice<T,D>::convert2Unit(const PA& pin, PA& pout) const
|
||||
{
|
||||
pout.setUnit(PosUnit::LatticeUnit);
|
||||
if(pin.getUnit() == PosUnit::LatticeUnit)
|
||||
pout = pin;
|
||||
else //need to convert to LatticeUnit
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = dot(pin[i],G);
|
||||
}
|
||||
|
||||
/** Conversion of a position array to Cartesian unit.
|
||||
*
|
||||
*@param pos in/out position array
|
||||
*
|
||||
*@note The unit of the out vector is forced to be Cartesian. If the unit
|
||||
*of pos is in Cartesian, no action is taken.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
inline void CrystalLattice<T,D>::convert2Cart(PA& pos) const
|
||||
{
|
||||
if(pos.getUnit() == PosUnit::LatticeUnit) {
|
||||
for(int i=0; i<pos.size(); i++) pos[i] = dot(pos[i],R);
|
||||
pos.setUnit(PosUnit::CartesianUnit);
|
||||
}
|
||||
}
|
||||
|
||||
/** Conversion of a position array to Lattice unit.
|
||||
*
|
||||
*@param pos in/out position array
|
||||
*
|
||||
*@note The unit of the out vector is forced to be in Lattice unit.
|
||||
*If the unit of pos is in Lattice unit, no action is taken.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
inline void CrystalLattice<T,D>::convert2Unit(PA& pos) const
|
||||
{
|
||||
if(pos.getUnit() == PosUnit::CartesianUnit) {
|
||||
for(int i=0; i<pos.size(); i++) pos[i] = dot(pos[i],G);
|
||||
pos.setUnit(PosUnit::LatticeUnit);
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy an in vector to an out vector after applying boundary conditions.
|
||||
*
|
||||
*@param pin an input position array
|
||||
*@param pout an output position array
|
||||
*@param del a tolerance for wrapping the values within [0,1)
|
||||
*
|
||||
*@note The values of pout are all within a bounding box.
|
||||
*The units of the in/out vectors are preserved. Numerical problems
|
||||
*can appear by using del=0 due to rounding errors. For instance,
|
||||
*when the box is partioned by 3x3x3, a terrible thing can happen.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
void
|
||||
CrystalLattice<T,D>::applyBC(const PA& pin, PA& pout, T del) const
|
||||
{
|
||||
int mode = pin.InUnit*2+pout.InUnit;
|
||||
switch(mode) {
|
||||
case(0):
|
||||
for(int i=0; i<pin.size(); i++)
|
||||
pout[i] = dot(BConds.wrap(dot(pin[i],G)+del),R);
|
||||
break;
|
||||
case(1):
|
||||
for(int i=0; i<pin.size(); i++)
|
||||
pout[i] = BConds.wrap(dot(pin[i],G)+del);
|
||||
break;
|
||||
case(2):
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = dot(BConds.wrap(pin[i]+del),R);
|
||||
break;
|
||||
case(3):
|
||||
for(int i=0; i<pin.size(); i++) pout[i] = BConds.wrap(pin[i]+del);
|
||||
break;
|
||||
}
|
||||
|
||||
// switch(mode) {
|
||||
// case(0):
|
||||
// for(int i=0; i<pin.size(); i++)
|
||||
// pout[i] = dot(BConds.wrap(dot(pin[i],G)),R);
|
||||
// break;
|
||||
// case(1):
|
||||
// for(int i=0; i<pin.size(); i++)
|
||||
// pout[i] = BConds.wrap(dot(pin[i],G));
|
||||
// break;
|
||||
// case(2):
|
||||
// for(int i=0; i<pin.size(); i++) pout[i] = dot(BConds.wrap(pin[i]),R);
|
||||
// break;
|
||||
// case(3):
|
||||
// for(int i=0; i<pin.size(); i++) pout[i] = BConds.wrap(pin[i]);
|
||||
// break;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/** Copy an in vector to an out vector after applying boundary conditions.
|
||||
*
|
||||
*@param pos an in/out position array
|
||||
*@param del a tolerance for wrapping the values within [0,1)
|
||||
*
|
||||
*@note The values of pos are all within a bounding box.
|
||||
*The unit is preserved. Numerical problems can appear
|
||||
*by using del=0 due to rounding errors.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
template<class PA>
|
||||
void CrystalLattice<T,D>::applyBC(PA& pos, T del) const
|
||||
{
|
||||
if(pos.InUnit) {
|
||||
for(int i=0; i<pos.size(); i++) pos[i] = BConds.wrap(pos[i]);
|
||||
} else {
|
||||
for(int i=0; i<pos.size(); i++) pos[i] = BConds.wrap(dot(pos[i],G)+del);
|
||||
pos.InUnit = true;
|
||||
}
|
||||
|
||||
// if(pos.InUnit) {
|
||||
// for(int i=0; i<pos.size(); i++) pos[i] = BConds.wrap(pos[i]);
|
||||
// } else {
|
||||
// for(int i=0; i<pos.size(); i++) pos[i] = BConds.wrap(dot(pos[i],G));
|
||||
// pos.InUnit = true;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,149 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2004- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
/**@file MakeCrystalLattice.h
|
||||
*@brief Functors to create a lattice with command-line options.
|
||||
*
|
||||
*The arguments are stored in std::vector<string>.
|
||||
*
|
||||
*/
|
||||
/** dummy template class to be specialized */
|
||||
template<class CL>
|
||||
struct makelattice { };
|
||||
|
||||
|
||||
/** Specialization of makelattice<CL> for CrystalLattice<T,D>
|
||||
*
|
||||
* Does nothing but enables specialization for D-dimensional lattice.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct makelattice<CrystalLattice<T,D> > {
|
||||
inline static void apply(CrystalLattice<T,D>& , vector<string>& argv) {
|
||||
}
|
||||
};
|
||||
|
||||
/** Specialization of makelattice<CL> for CrystalLattice<T,1>*/
|
||||
template<class T>
|
||||
struct makelattice<CrystalLattice<T,1> > {
|
||||
|
||||
inline static
|
||||
void
|
||||
apply(CrystalLattice<T,1>& lat, vector<string>& argv) {
|
||||
int i=0;
|
||||
int argc = argv.size();
|
||||
while(i<argc) {
|
||||
if(argv[i] == "a0") {
|
||||
lat.R(0,0) = atof(argv[++i].c_str());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
lat.reset();
|
||||
}
|
||||
};
|
||||
|
||||
/** Specialization of makelattice<CL> for CrystalLattice<T,2>*/
|
||||
template<class T>
|
||||
struct makelattice<CrystalLattice<T,2> > {
|
||||
|
||||
inline static
|
||||
void
|
||||
apply(CrystalLattice<T,2>& lat, vector<string>& argv) {
|
||||
T a0 = 1.0e0;
|
||||
int i=0;
|
||||
int argc = argv.size();
|
||||
while(i<argc) {
|
||||
if(argv[i] == "cubic") {
|
||||
a0 = atof(argv[++i].c_str());
|
||||
lat.R.diagonal(1.0);
|
||||
} else if(argv[i] == "orthorombic") {
|
||||
lat.R = 0.0e0;
|
||||
lat.R(0,0) = atof(argv[++i].c_str());
|
||||
lat.R(1,1) = atof(argv[++i].c_str());
|
||||
} else if(argv[i] == "general") {
|
||||
lat.R = 0.0e0;
|
||||
lat.R(0,0) = atof(argv[++i].c_str());
|
||||
lat.R(0,1) = atof(argv[++i].c_str());
|
||||
lat.R(1,0) = atof(argv[++i].c_str());
|
||||
lat.R(1,1) = atof(argv[++i].c_str());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
lat.R *= a0;
|
||||
lat.reset();
|
||||
}
|
||||
};
|
||||
|
||||
/** Specialization of makelattice<CL> for CrystalLattice<T,3>*/
|
||||
template<class T>
|
||||
struct makelattice<CrystalLattice<T,3> > {
|
||||
|
||||
/*! \fn makelattic<CrystalLattice<T,3> >
|
||||
* ::apply(CrystalLattice<T,3>& lattice, vector<string>& argv)
|
||||
* \param lattice an CrystalLattice to be set
|
||||
* \param argv input parameters
|
||||
* \note Keywords to set a speical 3D primitive cell.
|
||||
* \li \p lattice \p cubic \p a
|
||||
* \li \p lattice \p fcc \p a
|
||||
* \li \p lattice \p bcc \p a
|
||||
* \li \p lattice \p hcp \p a \p [c/a]
|
||||
*/
|
||||
inline static
|
||||
void
|
||||
apply(CrystalLattice<T,3>& lat, vector<string>& argv) {
|
||||
T a0 = 1.0e0;
|
||||
int i=0;
|
||||
int argc = argv.size();
|
||||
while(i<argc) {
|
||||
if(argv[i] == "cubic") {
|
||||
a0 = atof(argv[++i].c_str());
|
||||
lat.R.diagonal(1.0);
|
||||
} else if(argv[i] == "orthorombic") {
|
||||
lat.R = 0.0e0;
|
||||
lat.R(0,0) = atof(argv[++i].c_str());
|
||||
lat.R(1,1) = atof(argv[++i].c_str());
|
||||
lat.R(2,2) = atof(argv[++i].c_str());
|
||||
} else if(argv[i] == "fcc") {
|
||||
a0 = atof(argv[++i].c_str());
|
||||
lat.R(0,0) = 0.0; lat.R(0,1) = 0.5; lat.R(0,2) = 0.5;
|
||||
lat.R(1,0) = 0.5; lat.R(1,1) = 0.0; lat.R(1,2) = 0.5;
|
||||
lat.R(2,0) = 0.5; lat.R(2,1) = 0.5; lat.R(2,2) = 0.0;
|
||||
} else if(argv[i] == "bcc") {
|
||||
a0 = atof(argv[++i].c_str());
|
||||
lat.R(0,0) = -0.5; lat.R(0,1) = 0.5; lat.R(0,2) = 0.5;
|
||||
lat.R(1,0) = 0.5; lat.R(1,1) = -0.5; lat.R(1,2) = 0.5;
|
||||
lat.R(2,0) = 0.5; lat.R(2,1) = 0.5; lat.R(2,2) = -0.5;
|
||||
} else if(argv[i] == "hcp") {
|
||||
a0 = atof(argv[++i].c_str());
|
||||
double covera = sqrt(8.0/3.0);
|
||||
if(argc-i > 1) covera = atof(argv[++i].c_str());
|
||||
lat.R(0,0) = 0.5*a0; lat.R(0,1) = -sqrt(3.0)*0.5*a0; lat.R(0,2) = 0.0;
|
||||
lat.R(1,0) = 0.5*a0; lat.R(1,1) = sqrt(3.0)*0.5*a0; lat.R(1,2) = 0.0;
|
||||
lat.R(2,0) = 0.0; lat.R(2,1) = 0.0; lat.R(2,2) = covera*a0;
|
||||
a0 = 1.0e0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
lat.R *= a0;
|
||||
lat.reset();
|
||||
}
|
||||
};
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,241 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_MULTIGRID_PARTICLE_LAYOUT_H
|
||||
#define OHMMS_MULTIGRID_PARTICLE_LAYOUT_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
|
||||
#include "Lattice/Region.h"
|
||||
#include "Lattice/UniformCartesianGrid.h"
|
||||
|
||||
//forward declaration
|
||||
template<class T, unsigned D> class MakeMultiGrid;
|
||||
|
||||
/*! \class MultiGridParticleLayout<class T, unsigned D>
|
||||
* \brief A class for grid layout
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct MultiGridParticleLayout {
|
||||
|
||||
typedef UniformCartesianGrid<T,D> PtclGrid_t;
|
||||
|
||||
vector<PtclGrid_t*> dGrid;
|
||||
|
||||
MultiGridParticleLayout(){ }
|
||||
~MultiGridParticleLayout() {
|
||||
for(int i=0; i<dGrid.size(); i++)
|
||||
delete dGrid[i];
|
||||
}
|
||||
|
||||
inline const PtclGrid_t* getGrid(int level) const {
|
||||
return dGrid[level]; // return a grid at level
|
||||
}
|
||||
|
||||
|
||||
/*! \fn makeGrid(int *grid, int igrid=-1)
|
||||
* \param grid[D] a grid partition
|
||||
* \param igrid index of an existing grid to make a sub partition
|
||||
* \return the index of a new grid
|
||||
* \note if(igrid == -1) a new grid is created
|
||||
* else a new subgrid based on igrid-th grid is created
|
||||
*/
|
||||
int makeGrid(int *grid, int igrid=-1) {
|
||||
int n=dGrid.size();
|
||||
dGrid.push_back(new PtclGrid_t);
|
||||
if(igrid >= 0 && n>0)
|
||||
MakeMultiGrid<T,D>::refineGrid(*dGrid[n],*dGrid[igrid],grid);
|
||||
else
|
||||
MakeMultiGrid<T,D>::makeGrid(*dGrid[n],grid);
|
||||
return n;
|
||||
}
|
||||
|
||||
void resetGrid(int igrid, int* grid) {
|
||||
|
||||
if(igrid == dGrid.size()) {//need to create a new grid
|
||||
dGrid.push_back(new PtclGrid_t);
|
||||
}
|
||||
|
||||
if(igrid > 0) {
|
||||
MakeMultiGrid<T,D>::refineGrid(*dGrid[igrid],*dGrid[igrid-1],grid);
|
||||
} else {
|
||||
MakeMultiGrid<T,D>::makeGrid(*dGrid[igrid],grid);
|
||||
}
|
||||
}
|
||||
|
||||
void printGrid(ostream& os) {
|
||||
for(int i=0; i<dGrid.size(); i++) dGrid[i]->print(os);
|
||||
}
|
||||
|
||||
template<class P> void update(P*, int);
|
||||
};
|
||||
|
||||
|
||||
template<class T, unsigned D>
|
||||
struct MakeMultiGrid {};
|
||||
|
||||
template<class T>
|
||||
struct MakeMultiGrid<T,3> {
|
||||
|
||||
typedef UniformCartesianGrid<T,3> ThisGrid_t;
|
||||
|
||||
static void makeGrid(ThisGrid_t& grid, int* ng) {
|
||||
|
||||
int ngtot=ng[0]*ng[1]*ng[2];
|
||||
grid.set(ng);
|
||||
grid.NodeID.resize(ngtot);
|
||||
grid.NodeDist.resize(ngtot+1);
|
||||
grid.Node.resize(ngtot);
|
||||
|
||||
for(int i=0; i<=ngtot; i++) grid.NodeDist[i] = i;
|
||||
T ri[3];
|
||||
int ig=0;
|
||||
for(int ic=0; ic<grid.NP[0]; ic++) {
|
||||
ri[0] = grid.Delta[0]*static_cast<T>(ic);
|
||||
for(int jc=0; jc<grid.NP[1]; jc++) {
|
||||
ri[1] = grid.Delta[1]*static_cast<T>(jc);
|
||||
for(int kc=0; kc<grid.NP[2]; kc++) {
|
||||
ri[2] = grid.Delta[2]*static_cast<T>(kc);
|
||||
|
||||
grid.NodeID[grid.key(ic,jc,kc)] = ig;
|
||||
grid.Node[ig].set(ri,grid.Delta);
|
||||
ig++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
refineGrid(ThisGrid_t& subgrid, const ThisGrid_t& biggrid, int *ng) {
|
||||
|
||||
int ngbig = biggrid.NP[0]*biggrid.NP[1]*biggrid.NP[2];
|
||||
int ngsub = ng[0]*ng[1]*ng[2];
|
||||
int ngtot = ngbig*ngsub;
|
||||
int ngnew[3];
|
||||
|
||||
ngnew[0] = ng[0]*biggrid.NP[0];
|
||||
ngnew[1] = ng[1]*biggrid.NP[1];
|
||||
ngnew[2] = ng[2]*biggrid.NP[2];
|
||||
|
||||
subgrid.set(ngnew);
|
||||
subgrid.NodeID.resize(ngtot);
|
||||
subgrid.Node.resize(ngtot);
|
||||
|
||||
T ri[3],orig[3];
|
||||
|
||||
subgrid.NodeDist.resize(ngbig+1);
|
||||
subgrid.NodeDist[0] = 0;
|
||||
int igrid=0;
|
||||
|
||||
for(int ig=0; ig<biggrid.Node.size(); ig++) {
|
||||
|
||||
//origin of a mesh
|
||||
orig[0] = biggrid.Node[ig].Ri[0];
|
||||
orig[1] = biggrid.Node[ig].Ri[1];
|
||||
orig[2] = biggrid.Node[ig].Ri[2];
|
||||
|
||||
//integer indices of a mesh
|
||||
subgrid.getcoord(orig,ngnew);
|
||||
|
||||
//ngnew[0]*=ng[0]; ngnew[1]*=ng[1]; ngnew[2]*=ng[2];
|
||||
for(int isub=0; isub<ng[0]; isub++) {
|
||||
ri[0] = subgrid.Delta[0]*static_cast<T>(isub)+orig[0];
|
||||
for(int jsub=0; jsub<ng[1]; jsub++) {
|
||||
ri[1] = subgrid.Delta[1]*static_cast<T>(jsub)+orig[1];
|
||||
for(int ksub=0; ksub<ng[2]; ksub++) {
|
||||
ri[2] = subgrid.Delta[2]*static_cast<T>(ksub)+orig[2];
|
||||
subgrid.NodeID[subgrid.key(ngnew[0]+isub,
|
||||
ngnew[1]+jsub,
|
||||
ngnew[2]+ksub)] = igrid;
|
||||
subgrid.Node[igrid].set(ri,subgrid.Delta);
|
||||
igrid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
subgrid.NodeDist[ig+1] = subgrid.NodeDist[ig]+ngsub;
|
||||
}
|
||||
}
|
||||
|
||||
// //Intended for MPI_Cartesian functions but
|
||||
// #ifdef USE_MPI
|
||||
// static void makeMPIGrid(ThisGrid_t& grid, const int* ng, const int* period) {
|
||||
// int ngtot=ng[0]*ng[1]*ng[2];
|
||||
// grid.NodeID.resize(ngtot);
|
||||
// grid.NodeDist.resize(ngtot+1);
|
||||
// grid.Node.resize(ngtot);
|
||||
// for(int i=0; i<=ngtot; i++) grid.NodeDist[i] = i;
|
||||
// gird.set(ng);
|
||||
// Communicate* Comm = CommCreate::get();
|
||||
// int numnode = Comm->getNumNodes();
|
||||
// int nodeid = Comm->getNodeID(),newnode;
|
||||
// bool reorder = true;
|
||||
// MPI_Comm cartcomm;
|
||||
// int MyCoord[3];
|
||||
// // remapping a MPI grid using MPI_Cart
|
||||
// MPI_Cart_create(MPI_COMM_WORLD,3,grid.NP,period,reorder,&cartcomm);
|
||||
// MPI_Cart_map(cartcomm,3,grid.NP,period,&newnode);
|
||||
// MPI_Cart_get(cartcomm,3,grid.NP,period,MyCoord);
|
||||
// Comm->setNodeID(newnode);
|
||||
// Comm->setCommID(cartcomm);
|
||||
// int MyID = newnode;
|
||||
// int coord[3],ii=0;
|
||||
// double ri[3];
|
||||
// for(int i=0;i<ng[0]; i++) {
|
||||
// ri[0] = grid.Delta[0]*static_cast<double>(i);
|
||||
// for(int j=0; j<ng[1]; j++) {
|
||||
// ri[1] = grid.Delta[1]*static_cast<double>(j);
|
||||
// for(int k=0; k<ng[2]; k++) {
|
||||
// coord[0] = i; coord[1] = j; coord[2] = k;
|
||||
// MPI_Cart_rank(cartcomm,coord,&nodeid);
|
||||
// ri[2] = grid.Delta[2]*static_cast<double>(k);
|
||||
// grid.Node[nodeid].set(ri,grid.Delta);
|
||||
// grid.NodeID[grid.key(i,j,k)] = nodeid;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #endif
|
||||
};
|
||||
|
||||
template<class T, unsigned D>
|
||||
template<class P>
|
||||
void MultiGridParticleLayout<T,D>::update(P* ptcl, int imode) {
|
||||
|
||||
|
||||
// cout << "Calling MultiGridParticleLayout::update" << endl;
|
||||
// typedef P::ParticlePos_t ParticlePos_t;
|
||||
// typedef P::ParticleIndex_t ParticleIndex_t;
|
||||
|
||||
// ParticlePos_t r;
|
||||
// ParticlePos_t id;
|
||||
|
||||
// r.resize(ptcl->getLocalNum());
|
||||
// id.resize(ptcl->getLocalNum());
|
||||
|
||||
// r = ptcl->R;
|
||||
// id = ptcl->IonID;
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,282 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
/***************************************************************************
|
||||
*
|
||||
* The POOMA Framework
|
||||
*
|
||||
* This program was prepared by the Regents of the University of
|
||||
* California at Los Alamos National Laboratory (the University) under
|
||||
* Contract No. W-7405-ENG-36 with the U.S. Department of Energy (DOE).
|
||||
* The University has certain rights in the program pursuant to the
|
||||
* contract and the program should not be copied or distributed outside
|
||||
* your organization. All rights in the program are reserved by the DOE
|
||||
* and the University. Neither the U.S. Government nor the University
|
||||
* makes any warranty, express or implied, or assumes any liability or
|
||||
* responsibility for the use of this software
|
||||
*
|
||||
* Visit http://www.acl.lanl.gov/POOMA for more details
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PARTICLE_BCONDS_H
|
||||
#define PARTICLE_BCONDS_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*! \note Modification of ParticleBConds.h of Pooma r1 to work with
|
||||
* changed TinyVector classes.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// particle boundary condition functions ...
|
||||
// ParticleNoBCond = no action is taken
|
||||
// ParticlePeriodicBCond = shift the vector withtin [-len/2, len/2)
|
||||
// ParticlePeriodicWrapBCond = wrap around at endpoints of the interval
|
||||
// ParticleReflectiveBCond = values bounce back from endpoints
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// null BC; value is not changed
|
||||
|
||||
|
||||
//! \param t A position subject to the boundary condition.
|
||||
//! \param minval mininum range (ignored)
|
||||
//! \param maxval maximum range (ignored)
|
||||
//! \return t
|
||||
template<class T>
|
||||
inline T
|
||||
ParticleNoBCond(const T t, const T /* minval */, const T /* maxval */) {
|
||||
return t;
|
||||
}
|
||||
|
||||
//! \param t A position subject to the boundary condition.
|
||||
//! \param minval mininum range (ignored)
|
||||
//! \param maxval maximum range (ignored)
|
||||
//! \return t if |t| < (maxval-minval)/2
|
||||
//! \note This funtion returns the shortest distance of
|
||||
//! t under periodic boundary condition. minval is ignored for periodic BC.
|
||||
//! [-maxval/2, maxval/2) is the actual range
|
||||
template<class T>
|
||||
inline T
|
||||
ParticlePeriodicBCond(const T t, const T minval, const T maxval) {
|
||||
//T t0=fmod(t,maxval);
|
||||
//return t0 - static_cast<T>(static_cast<int>(t0*2.0*maxval));
|
||||
if(t < -0.5) return t+1.0;
|
||||
else if(t>= 0.5) return t-1.0;
|
||||
else return t;
|
||||
}
|
||||
|
||||
//! \param t A position subject to the boundary condition.
|
||||
//! \param minval mininum range (ignored)
|
||||
//! \param maxval maximum range (ignored)
|
||||
//! \return t
|
||||
//! \note Poomar1::ParticlePeriodicBCond is ParticlePeriodicWrapBCond
|
||||
template<class T>
|
||||
inline T
|
||||
ParticlePeriodicWrapBCond(const T t, const T minval, const T maxval) {
|
||||
if (t < minval)
|
||||
return (maxval - (minval - t));
|
||||
else if (t >= maxval)
|
||||
return (minval + (t - maxval));
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
//! \note reflective BC; values bounce back from endpoints
|
||||
//! Implemented by Poomar1.
|
||||
template<class T>
|
||||
inline T
|
||||
ParticleReflectiveBCond(const T t, const T minval, const T maxval) {
|
||||
if (t < minval)
|
||||
return (minval + (minval - t));
|
||||
else if (t >= maxval)
|
||||
return (maxval - (t - maxval));
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
//! \note sink BC; particles stick to the selected face
|
||||
//! Implemented by Poomar1
|
||||
template<class T>
|
||||
T ParticleSinkBCond(const T t, const T minval, const T maxval) {
|
||||
if (t < minval)
|
||||
return minval;
|
||||
else if (t >= maxval)
|
||||
return maxval;
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fuction classes to apply BC to a TinyVector
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
// forward declaration
|
||||
template<class T, unsigned D> class ParticleBConds;
|
||||
|
||||
/*! \class template<class T> struct applyBConds
|
||||
* \brief Empty class. Specialization of applyBConds with specific
|
||||
* ParticleBConds is intended.
|
||||
*/
|
||||
template<class T>
|
||||
struct applyBConds {
|
||||
};
|
||||
|
||||
/*!\class template<class T, unsigned D> struct applyBConds<ParticleBConds<T,D> >
|
||||
* \brief Specialization for ParticleBConds<T,D> defined below.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct applyBConds<ParticleBConds<T,D> > {
|
||||
|
||||
//!< Apply boundary conditions for each direction
|
||||
static inline TinyVector<T,D>
|
||||
apply(const ParticleBConds<T,D>& bc, const TinyVector<T,D>& a){
|
||||
TinyVector<T,D> res;
|
||||
for(int i=0; i<D; i++) res[i] = bc.apply(a[i],i,1.0);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
/*!\class template<class T> struct applyBConds<ParticleBConds<T,1> >
|
||||
* \brief Specialization for ParticleBConds<T,D> defined below.
|
||||
*/
|
||||
template<class T>
|
||||
struct applyBConds<ParticleBConds<T,1> > {
|
||||
|
||||
static inline TinyVector<T,1>
|
||||
apply(const ParticleBConds<T,1>& bc, const TinyVector<T,1>& a){
|
||||
return
|
||||
TinyVector<T,1>(bc.apply(a[0],0,1));
|
||||
}
|
||||
};
|
||||
|
||||
/*!\class template<class T> struct applyBConds<ParticleBConds<T,2> >
|
||||
* \brief Specialization for ParticleBConds<T,D> defined below.
|
||||
*/
|
||||
template<class T>
|
||||
struct applyBConds<ParticleBConds<T,2> > {
|
||||
|
||||
static inline TinyVector<T,2>
|
||||
apply(const ParticleBConds<T,2>& bc, const TinyVector<T,2>& a){
|
||||
return
|
||||
TinyVector<T,2>(bc.apply(a[0],0,1),bc.apply(a[1],1,1));
|
||||
}
|
||||
};
|
||||
|
||||
/*!\class template<class T> struct applyBConds<ParticleBConds<T,3> >
|
||||
* \brief Specialization for ParticleBConds<T,D> defined below.
|
||||
*/
|
||||
template<class T>
|
||||
struct applyBConds<ParticleBConds<T,3> > {
|
||||
|
||||
static inline TinyVector<T,3>
|
||||
apply(const ParticleBConds<T,3>& bc, const TinyVector<T,3>& a){
|
||||
return
|
||||
TinyVector<T,3>(bc.apply(a[0],0,1),bc.apply(a[1],1,1),bc.apply(a[2],2,1));
|
||||
}
|
||||
|
||||
static inline TinyVector<T,3>
|
||||
wrap(const ParticleBConds<T,3>& bc, const TinyVector<T,3>& a){
|
||||
return
|
||||
TinyVector<T,3>(bc.wrap(a[0],0,1),bc.wrap(a[1],1,1),
|
||||
bc.wrap(a[2],2,1));
|
||||
}
|
||||
};
|
||||
|
||||
/*!\class ParticleBConds
|
||||
* \brief ParticleBConds is a container for a set of particle boundary condition
|
||||
* functions. Boundary conditions for particles are not objects, but just
|
||||
* functions which map a position X -> X', given the minimum and maximum
|
||||
* values of the spatial domain.
|
||||
***************************************************************************/
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// general container for a set of particle boundary conditions
|
||||
template<class T, unsigned Dim>
|
||||
class ParticleBConds {
|
||||
|
||||
public:
|
||||
// typedef for a pointer to boundary condition function
|
||||
typedef T (*ParticleBCond)(const T, const T, const T);
|
||||
|
||||
public:
|
||||
// constructor: initialize all BC's to periodic ones
|
||||
ParticleBConds() {
|
||||
for (int d=(Dim - 1); d >= 0; --d) {
|
||||
BCList[d] = ParticlePeriodicBCond; // for distance
|
||||
BCTransList[d] = ParticlePeriodicWrapBCond; // for translation, wrapping
|
||||
}
|
||||
}
|
||||
|
||||
// operator= to copy values from another container
|
||||
ParticleBConds<T,Dim>& operator=(const ParticleBConds<T,Dim>& pbc) {
|
||||
for (int d=(Dim - 1); d >= 0; --d) {
|
||||
BCList[d] = pbc.BCList[d];
|
||||
BCTransList[d] = ParticlePeriodicWrapBCond;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// operator[] to get value of Nth boundary condition
|
||||
inline ParticleBCond& operator[](unsigned d) { return BCList[d]; }
|
||||
|
||||
// return a wrpper function for d-direction
|
||||
inline ParticleBCond& wrapper(unsigned d) { return BCTransList[d]; }
|
||||
|
||||
// for the given value in the given dimension over the given NDRegion,
|
||||
// apply the proper BC and return back the new value
|
||||
inline T apply(const T t, const unsigned d, const T len) const {
|
||||
return BCList[d](t,0,len);
|
||||
}
|
||||
|
||||
// for the given value in the given dimension over the given NDRegion,
|
||||
// apply the proper BC and return back the new value
|
||||
inline T wrap(const T t, const unsigned d, const T len) const {
|
||||
return BCTransList[d](t,0,len);
|
||||
}
|
||||
|
||||
// to work with difffent types of data
|
||||
template<class T1>
|
||||
inline T1 apply(const T1 t, const unsigned d, const T1 len) const {
|
||||
return static_cast<T1>(
|
||||
BCList[d](static_cast<T>(t), 0, static_cast<T>(len)));
|
||||
}
|
||||
|
||||
inline TinyVector<T,Dim> apply(const TinyVector<T,Dim>& x) const {
|
||||
return applyBConds<ParticleBConds<T,Dim> >::apply(*this,x);
|
||||
}
|
||||
|
||||
inline TinyVector<T,Dim> wrap(const TinyVector<T,Dim>& x) const {
|
||||
|
||||
return applyBConds<ParticleBConds<T,Dim> >::wrap(*this,x);
|
||||
}
|
||||
|
||||
private:
|
||||
// array storing the function pointers
|
||||
// Note that the size is Dim not 2*Dim
|
||||
ParticleBCond BCList[Dim];
|
||||
ParticleBCond BCTransList[Dim];
|
||||
};
|
||||
|
||||
#endif // PARTICLE_BCONDS_H
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,93 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_REGULARMULTIGRID_H
|
||||
#define OHMMS_REGULARMULTIGRID_H
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
/*! \class RegMultiGrid<class T, unsigned D>
|
||||
* \brief A class for grid layout using octree
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct RegMultiGrid {
|
||||
|
||||
typedef RegMultiGrid<T,D> this_t;
|
||||
Region<T,D> R;
|
||||
|
||||
RegMultiGrid():Up(NULL){ }
|
||||
~RegMultiGrid();
|
||||
|
||||
inline bool root() const { return Up == NULL;}
|
||||
inline bool empty() const { return Down.empty();}
|
||||
|
||||
inline const RegMultiGrid* node() const { return Up;}
|
||||
inline const RegMultiGrid* child(int i) const {
|
||||
if(Down.empty()) return NULL;
|
||||
else return Down[i];
|
||||
}
|
||||
|
||||
void refine();
|
||||
|
||||
void remove() {
|
||||
for(int i=0; i<Down.size(); i++) delete Down[i];
|
||||
}
|
||||
|
||||
template<class pos_t>
|
||||
inline int node(const pos_t& pos) {
|
||||
if(R.inside(pos))
|
||||
return R.inside(pos);
|
||||
}
|
||||
|
||||
this_t* Up;
|
||||
vector<this_t* > Down;
|
||||
};
|
||||
|
||||
template<class T, unsigned D>
|
||||
RegMultiGrid<T,D>::~RegMultiGrid() {
|
||||
for(int i=0; i<Down.size(); i++) delete Down[i];
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
void RegMultiGrid<T,D>::refine() {}
|
||||
|
||||
template<class T>
|
||||
void RegMultiGrid<T,3>::refine() {
|
||||
|
||||
if(Down.empty()) {
|
||||
for(int i=0; i<8; i++) Down.push_back(new RegMultGrid<T,D>);
|
||||
T dx[D];
|
||||
dx[0] = R.Rf[0]-R.Ri[0];
|
||||
dx[1] = R.Rf[1]-R.Ri[1];
|
||||
dx[2] = R.Rf[2]-R.Ri[2];
|
||||
|
||||
for(int idim=0; idim<D; idim++)
|
||||
dx[idim] = (R.Rf[idim]-R.Ri[dim])*0.5;
|
||||
|
||||
}
|
||||
if(Down.empty()) {
|
||||
for(int i=0; i<nsub; i++) Down.push_back(new RegMultGrid<T,D>);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,72 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_REGINON_H
|
||||
#define OHMMS_REGION_H
|
||||
|
||||
/* \class Region defines a spatial region bound by [Ri,Rf)
|
||||
\brief Defined in unit vectors 0 <= Ri, Rf < 1
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct Region {
|
||||
|
||||
typedef T Scalar_t;
|
||||
enum {DIM = D};
|
||||
T Ri[D], Rf[D];
|
||||
|
||||
Region(){ }
|
||||
|
||||
Region(const T* r0, const T* dr) {
|
||||
set(r0,dr);
|
||||
}
|
||||
|
||||
Region(const Region<T,D>& rg) {
|
||||
for(int i=0; i<D; i++) Ri[i] = rg.Ri[i];
|
||||
for(int i=0; i<D; i++) Rf[i] = rg.Rf[i];
|
||||
}
|
||||
|
||||
Region<T,D>& operator=(const Region<T,D>& rg) {
|
||||
for(int i=0; i<D; i++) Ri[i] = rg.Ri[i];
|
||||
for(int i=0; i<D; i++) Rf[i] = rg.Rf[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Region(){ }
|
||||
|
||||
inline void set(const T* r0, const T* dr) {
|
||||
for(int i=0; i<D; i++) Ri[i] = r0[i];
|
||||
for(int i=0; i<D; i++) Rf[i] = r0[i]+dr[i];
|
||||
}
|
||||
|
||||
template<class Pos_t>
|
||||
inline bool inside(const Pos_t& r) const {
|
||||
for(int i=0; i<DIM; i++) {
|
||||
if(r[i] < Ri[i] || r[i] >= Rf[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,275 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_UNIFORMCARTESIANGRID_H
|
||||
#define OHMMS_UNIFORMCARTESIANGRID_H
|
||||
|
||||
/**@file UniformCartesianGrid.h
|
||||
*@brief Class declarations for UniformCartesianGrid
|
||||
*/
|
||||
#include "Utilities/DistributedIndex.h"
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include <iostream>
|
||||
|
||||
/* \class UniformCartesianGrid
|
||||
* \brief Class to manage a uniform grid.
|
||||
*
|
||||
* Does nothing and needs to be specialized.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct UniformCartesianGrid {};
|
||||
|
||||
/** Specialization of UniformCartesianGrid<T,D> to 3-Dim domains.
|
||||
*
|
||||
*Regardless of the shape of the domain, the view of UniformCartesianGrid
|
||||
*is a cubic cell. The 3-D position vector is valid only if \f$v = ([0,1),[0,1),[0,1))\f$.
|
||||
*
|
||||
*The main function of this class is to partition a domain defined by
|
||||
*3 orthogonal axes, \f${\hat x}, {\hat y}\f$ and \f${\hat z}\f$.
|
||||
*A region or domain is specified by three indices (i,j,k)
|
||||
*and they satisfy the conditions \f[ i \in [0,NP[0])\f] \f[ j \in
|
||||
*[0,NP[1])\f] \f[ k \in [0,NP[2])\f] The subdomains are stored in an
|
||||
*one-dimensional array and key is used to map (i,j,k) to the
|
||||
*corresponding domain. Member function key is provided in
|
||||
*anticipation of the need to use a sparse storage of the subdomains
|
||||
*to handle inhomogeneous systems.
|
||||
*/
|
||||
template<class T>
|
||||
class UniformCartesianGrid<T,3> {
|
||||
|
||||
public:
|
||||
|
||||
typedef DistributedIndex::iterator iterator;
|
||||
typedef DistributedIndex::const_iterator const_iterator;
|
||||
|
||||
///default constructor
|
||||
inline UniformCartesianGrid() {
|
||||
NumGrids = 1;
|
||||
NP[0] = 1; NP[1] = 1; NP[2] = 1;
|
||||
Delta[0] = 1; Delta[1] = 1; Delta[2] =1;
|
||||
InvDelta[0] = 1; InvDelta[1] = 1; InvDelta[2] =1;
|
||||
}
|
||||
|
||||
///copy constructor
|
||||
inline UniformCartesianGrid(const UniformCartesianGrid<T,3>& gr) {
|
||||
makeCopy(gr);
|
||||
}
|
||||
|
||||
/**constructor
|
||||
*@param ng a 3-Dim index vector that sets the partition
|
||||
*/
|
||||
template<class IV>
|
||||
inline UniformCartesianGrid(const IV& ng) {setGrid(ng);}
|
||||
|
||||
|
||||
///destructor
|
||||
virtual inline ~UniformCartesianGrid() { }
|
||||
|
||||
///copy operator
|
||||
UniformCartesianGrid<T,3>& operator=(const UniformCartesianGrid<T,3>& gr) {
|
||||
makeCopy(gr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///copy function
|
||||
inline void makeCopy(const UniformCartesianGrid<T,3>& gr) {
|
||||
setGrid(gr.NP);
|
||||
}
|
||||
|
||||
///return the number of grid in the i-th direction
|
||||
inline int size(int i) const { return NP[i];}
|
||||
|
||||
/**set the parameters to partition a 3-Dim domain
|
||||
*@param ng a 3-Dim index vector that sets the partition
|
||||
*/
|
||||
template<class IV>
|
||||
void setGrid(const IV& ng) {
|
||||
NumGrids = ng[0]*ng[1]*ng[2];
|
||||
NP[0] = ng[0]; NP[1] = ng[1]; NP[2] = ng[2];
|
||||
InvDelta[0] =static_cast<T>(ng[0]);
|
||||
InvDelta[1] =static_cast<T>(ng[1]);
|
||||
InvDelta[2] =static_cast<T>(ng[2]);
|
||||
Delta[0] =1./InvDelta[0];
|
||||
Delta[1] =1./InvDelta[1];
|
||||
Delta[2] =1./InvDelta[2];
|
||||
}
|
||||
|
||||
///return the total number of sub domains/grids
|
||||
inline int getTotalNum() const { return NumGrids;}
|
||||
|
||||
/**get a unique key for a domain(i,j,k)
|
||||
@param i the index of the first dimension
|
||||
@param j the index of the second dimension
|
||||
@param k the index of the third dimension
|
||||
@return the key for a domain(i,j,k)
|
||||
*/
|
||||
inline int key(int i, int j, int k) const {
|
||||
return k+NP[2]*(j+NP[1]*i);
|
||||
}
|
||||
|
||||
/**get a index of a domain(i,j,k)
|
||||
@param i the index of the first dimension
|
||||
@param j the index of the second dimension
|
||||
@param k the index of the third dimension
|
||||
@return the storage index of a domain(i,j,k)
|
||||
*/
|
||||
inline int loc(int i, int j, int k) const {
|
||||
return k+NP[2]*(j+NP[1]*i);
|
||||
}
|
||||
|
||||
/**get a domain index of a 3-D vector v(x,y,z)
|
||||
@param x the position in the first dimension
|
||||
@param y the position in the second dimension
|
||||
@param z the position in the third dimension
|
||||
@return the storage index of a domain whose position is p(x,y,z)
|
||||
*/
|
||||
inline int loc(T x, T y, T z) const {
|
||||
return int(z*InvDelta[2])+NP[2]*(int(y*InvDelta[1])+
|
||||
NP[1]*int(x*InvDelta[0]));
|
||||
}
|
||||
|
||||
/**get a domain index of a 3-D vector p
|
||||
@param p a 3-D vector with operator[]
|
||||
@return the storage index of a domain whose position is p
|
||||
*/
|
||||
template<class Pos_t>
|
||||
inline
|
||||
int loc(const Pos_t& p) const {
|
||||
return
|
||||
int(p[2]*InvDelta[2])
|
||||
+NP[2]*(int(p[1]*InvDelta[1])+NP[1]*int(p[0]*InvDelta[0]));
|
||||
}
|
||||
|
||||
/**get a 3-D index vector for a position r
|
||||
*@param r the position
|
||||
*@return a index vector containing the cell indices in the three directions
|
||||
*/
|
||||
inline TinyVector<int,3> index(const TinyVector<T,3>& r) {
|
||||
return TinyVector<int,3>(static_cast<int>(r[0]*InvDelta[0]),
|
||||
static_cast<int>(r[1]*InvDelta[1]),
|
||||
static_cast<int>(r[2]*InvDelta[2]));
|
||||
}
|
||||
|
||||
/**get a center position of a domain(i,j,k)
|
||||
@param i the index of the first dimension
|
||||
@param j the index of the second dimension
|
||||
@param k the index of the third dimension
|
||||
@return the position of the domain(i,j,k)
|
||||
*/
|
||||
inline TinyVector<T,3> center(int i, int j, int k) const {
|
||||
return TinyVector<T,3>((static_cast<T>(i)+0.5)*Delta[0],
|
||||
(static_cast<T>(j)+0.5)*Delta[1],
|
||||
(static_cast<T>(k)+0.5)*Delta[2]);
|
||||
}
|
||||
|
||||
/**distribute the domains over the processors
|
||||
*@param ntot the total number of processors
|
||||
*
|
||||
*The processor can be a MPI node or an OpenMP thread.
|
||||
*The domains are distributed over the processors as evenly as possible.
|
||||
*However, the computataionl nodes are not factored in for load balancing.
|
||||
*/
|
||||
inline void distribute(int ntot) {
|
||||
I.distribute(ntot,NumGrids);
|
||||
}
|
||||
|
||||
/**distribute the domains over the processors [first, last)
|
||||
*@param first iterator for the starting node
|
||||
*@param last iterator for the ending node
|
||||
*
|
||||
*A similar function to the void distribute(int ntot).
|
||||
*/
|
||||
template <class _InputIterator>
|
||||
void distribute(_InputIterator first, _InputIterator last) {
|
||||
I.distribute(first,last);
|
||||
}
|
||||
|
||||
/**print the domain partition information
|
||||
*@param os ostream to write to
|
||||
*
|
||||
*This is for debug/test only.
|
||||
*/
|
||||
void printGrid(std::ostream& os) const {
|
||||
const int nw = 15;
|
||||
os << "number of sub regions " << NumGrids << endl;
|
||||
os << "Attribute distribution = " << endl;
|
||||
os << "grid spacing = " << setw(nw) << Delta[0] << setw(nw) << Delta[1]
|
||||
<< setw(nw) << Delta[2] << endl;
|
||||
|
||||
TinyVector<T,3> origin;
|
||||
for(int ig=0; ig<NP[0]; ig++) {
|
||||
origin[0] = static_cast<T>(ig)*Delta[0];
|
||||
for(int jg=0; jg<NP[1]; jg++) {
|
||||
origin[1] = static_cast<T>(jg)*Delta[1];
|
||||
for(int kg=0; kg<NP[2]; kg++) {
|
||||
origin[2] = static_cast<T>(kg)*Delta[2];
|
||||
os << setw(nw) << origin[0] << " | " << setw(nw) << origin[0]+Delta[0]
|
||||
<< setw(nw) << origin[1] << " | " << setw(nw) << origin[1]+Delta[1]
|
||||
<< setw(nw) << origin[2] << " | " << setw(nw) << origin[2]+Delta[2]
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** resize the grouping of domains
|
||||
*@param ng the number of groups
|
||||
*/
|
||||
inline void resizeGroup(int ng) { PID.resize(ng);}
|
||||
|
||||
///return the processor ID of the group ig
|
||||
inline int group(int ig) const { return PID[ig]; }
|
||||
///assign the processor ID of the group ig
|
||||
inline int& group(int ig) { return PID[ig];}
|
||||
|
||||
inline void createData() { I.create(NumGrids);}
|
||||
inline void clearData() { I.clear(); }
|
||||
inline void addData(int ig, int iat) {I.add(ig,iat);}
|
||||
|
||||
inline DistributedIndex& getDataSets() { return I;}
|
||||
inline const DistributedIndex& getDataSets() const { return I;}
|
||||
|
||||
inline int getNumData() const {return I.getNumData();}
|
||||
inline int getMaxDataPerGrid() const {return I.capacity();}
|
||||
inline int getNumDataSets() const { return I.getNumDataSets();}
|
||||
inline int firstData(int i) const { return I.M[i];}
|
||||
inline int lastData(int i) const { return I.M[i+1];}
|
||||
inline iterator beginData(int i) { return I.begin(i);}
|
||||
inline iterator endData(int i) { return I.end(i);}
|
||||
inline const_iterator beginData(int i) const { return I.begin(i);}
|
||||
inline const_iterator endData(int i) const { return I.end(i);}
|
||||
|
||||
void printData(std::ostream& os) const {
|
||||
I.print(os);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int NumGrids, NP[3];
|
||||
T Delta[3],InvDelta[3];
|
||||
DistributedIndex I;
|
||||
std::vector<int> PID;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,254 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_GRID_CONNECTION_H
|
||||
#define OHMMS_GRID_CONNECTION_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "Lattice/CrystalLattice.h"
|
||||
|
||||
/* \class GridConnection
|
||||
\brief templated over scalar type, dimension and a key to
|
||||
make connection list, similar to the nearest neighbor lists
|
||||
*/
|
||||
|
||||
template<class T, unsigned D>
|
||||
struct UniformGridConnection {};
|
||||
|
||||
// specialization
|
||||
template<class T>
|
||||
struct UniformGridConnection<T,3> {
|
||||
|
||||
typedef CrystalLattice<T,3> ParticleLayout_t;
|
||||
typedef typename ParticleLayout_t::SingleParticlePos_t SingleParticlePos_t;
|
||||
|
||||
vector<int> M;
|
||||
vector<int> ID;
|
||||
vector<SingleParticlePos_t> BC;
|
||||
|
||||
UniformGridConnection() { }
|
||||
|
||||
//!< return the first mesh connected to the ig grid
|
||||
inline int first(int ig) const { return M[ig];}
|
||||
|
||||
//!< return the last mesh connected to the ig grid
|
||||
inline int last(int ig) const { return M[ig+1];}
|
||||
|
||||
//!< return the mesh index
|
||||
inline int id(int j) const { return ID[j];}
|
||||
|
||||
//!< return the correction vector according to the boundary conditions
|
||||
inline SingleParticlePos_t bc(int j) const { return BC[j];}
|
||||
|
||||
//!< return the maximum number of connected cells
|
||||
inline int connect(const CrystalLattice<T,3>& Lattice, T rmax, int glevel) {
|
||||
|
||||
const typename ParticleLayout_t::PtclGrid_t& basegrid = *(Lattice.dGrid[glevel]);
|
||||
|
||||
SingleParticlePos_t u0(basegrid.Delta[0],0.0,0.0);
|
||||
SingleParticlePos_t u1(0.0,basegrid.Delta[1],0.0);
|
||||
SingleParticlePos_t u2(0.0,0.0,basegrid.Delta[2]);
|
||||
T RmaxSq = rmax*rmax;
|
||||
|
||||
///calculate the extend of linked cells
|
||||
int nx = static_cast<int>(sqrt(RmaxSq/Lattice.Dot(u0,u0)))+1;
|
||||
int ny = static_cast<int>(sqrt(RmaxSq/Lattice.Dot(u1,u1)))+1;
|
||||
int nz = static_cast<int>(sqrt(RmaxSq/Lattice.Dot(u2,u2)))+1;
|
||||
|
||||
M.resize(basegrid.getTotalNum()+1);
|
||||
int ntot = basegrid.getTotalNum()*nx*ny*nz;
|
||||
if(ID.size() < ntot) ID.reserve(ntot);
|
||||
if(BC.size() < ntot) BC.reserve(ntot);
|
||||
|
||||
M[0] = 0;
|
||||
int maxnc = 0;
|
||||
SingleParticlePos_t dx(basegrid.Delta[0], basegrid.Delta[1], basegrid.Delta[2]);
|
||||
|
||||
///for each grid, search for connected grids
|
||||
for(int ig=0; ig<basegrid.getTotalNum(); ig++) {
|
||||
|
||||
SingleParticlePos_t org(basegrid.Node[ig].Ri[0]+0.5*dx[0],
|
||||
basegrid.Node[ig].Ri[1]+0.5*dx[1],
|
||||
basegrid.Node[ig].Ri[2]+0.5*dx[2]),d;
|
||||
T x,y,z;
|
||||
int nconnected = 0;
|
||||
for(int ix=-nx; ix<=nx; ix++) {
|
||||
d[0] = x = org[0]+double(ix)*dx[0];
|
||||
if(Lattice.BoxBConds[0]) {
|
||||
x = fmod(d[0],1.0); if(x<0) x += 1.0;
|
||||
}
|
||||
if(x<0 || x>=1) continue;
|
||||
d[0] -= x;
|
||||
for(int jx=-ny; jx<=ny; jx++) {
|
||||
d[1] = y = org[1]+double(jx)*dx[1];
|
||||
if(Lattice.BoxBConds[1]) {
|
||||
y = fmod(d[1],1.0); if(y<0) y += 1.0;
|
||||
}
|
||||
if(y<0 || y>=1) continue;
|
||||
d[1] -= y;
|
||||
for(int kx=-nz; kx<=nz; kx++) {
|
||||
|
||||
///exclude itself
|
||||
if(ix == 0 && jx == 0 && kx == 0) continue;
|
||||
|
||||
d[2] = z = org[2]+double(kx)*dx[2];
|
||||
if(Lattice.BoxBConds[2]) {
|
||||
z = fmod(d[2],1.0); if(z<0) z += 1.0;
|
||||
}
|
||||
if(z<0 || z>=1) continue;
|
||||
d[2] -= z;
|
||||
|
||||
ID.push_back(basegrid.loc(x,y,z));
|
||||
BC.push_back(Lattice.toCart(d));
|
||||
nconnected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
M[ig+1] = M[ig]+nconnected;
|
||||
maxnc = max(maxnc,nconnected);
|
||||
}
|
||||
|
||||
// //for each grid, search for connected grid
|
||||
// for(int ig=0; ig<basegrid.getTotalNum(); ig++) {
|
||||
// cout << ig << " has " << M[ig+1]-M[ig] << endl;
|
||||
// for(int j=M[ig]; j<M[ig+1]; j++) {
|
||||
// cout << ID[j] << " " << BC[j] << endl;
|
||||
// }
|
||||
// }
|
||||
return maxnc; // return the maxmimum number of connected cells
|
||||
}
|
||||
/*** Extremely inefficient: using the new method above
|
||||
inline int connect(const CrystalLattice<T,3>& Lattice, T rmax, int glevel) {
|
||||
|
||||
T RmaxSq = rmax*rmax;
|
||||
|
||||
SingleParticlePos_t u0(1.0,0.0,0.0);
|
||||
SingleParticlePos_t u1(0.0,1.0,0.0);
|
||||
SingleParticlePos_t u2(0.0,0.0,1.0);
|
||||
|
||||
int maxx1 = static_cast<int>(sqrt( RmaxSq/Lattice.Dot(u0,u0))) + 1;
|
||||
int maxx2 = static_cast<int>(sqrt( RmaxSq/Lattice.Dot(u1,u1))) + 1;
|
||||
int maxx3 = static_cast<int>(sqrt( RmaxSq/Lattice.Dot(u2,u2))) + 1;
|
||||
|
||||
if(!Lattice.BoxBConds[0]) maxx1 = 0;
|
||||
if(!Lattice.BoxBConds[1]) maxx2 = 0;
|
||||
if(!Lattice.BoxBConds[2]) maxx3 = 0;
|
||||
|
||||
// using multimap to sort image cells
|
||||
multimap<int,SingleParticlePos_t> N;
|
||||
|
||||
// add the origin
|
||||
N.insert(pair<int,SingleParticlePos_t>(0,SingleParticlePos_t(0.0)));
|
||||
|
||||
//summation over the direct lattice
|
||||
for(int ix1=-maxx1; ix1<=maxx1; ix1++) {
|
||||
for(int ix2=-maxx2; ix2<=maxx2; ix2++) {
|
||||
for(int ix3=-maxx3; ix3<=maxx3; ix3++) {
|
||||
if(ix1 == 0 && ix2 == 0 && ix3 == 0) continue;
|
||||
SingleParticlePos_t xlp(static_cast<T>(ix1),
|
||||
static_cast<T>(ix2),
|
||||
static_cast<T>(ix3));
|
||||
|
||||
// using ix1^2+ix2^2+ix3^3 as key to sort the image cells
|
||||
N.insert(pair<int,SingleParticlePos_t>(ix1*ix1+ix2*ix2+ix3*ix3, xlp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const typename ParticleLayout_t::PtclGrid_t&
|
||||
basegrid = *(Lattice.dGrid[glevel]);
|
||||
SingleParticlePos_t dx(1.0/basegrid.Delta[0],
|
||||
1.0/basegrid.Delta[1],
|
||||
1.0/basegrid.Delta[2]);
|
||||
|
||||
int maxnc = 0;
|
||||
|
||||
M.resize(basegrid.getTotalNum()+1);
|
||||
int ntot = basegrid.getTotalNum()*N.size();
|
||||
if(ID.size() < ntot) ID.reserve(ntot);
|
||||
if(BC.size() < ntot) BC.reserve(ntot);
|
||||
|
||||
M[0] = 0;
|
||||
|
||||
//for each grid, search for connected grid
|
||||
for(int ig=0; ig<basegrid.getTotalNum(); ig++) {
|
||||
|
||||
SingleParticlePos_t org(basegrid.Node[ig].Ri[0],
|
||||
basegrid.Node[ig].Ri[1],
|
||||
basegrid.Node[ig].Ri[2]);
|
||||
|
||||
typename multimap<int,SingleParticlePos_t>::iterator it = N.begin();
|
||||
int ibox = 0;
|
||||
int nconnected = 0;
|
||||
|
||||
while(it != N.end()) {
|
||||
|
||||
SingleParticlePos_t displ = (*it).second;
|
||||
|
||||
for(int jg=0; jg<basegrid.getTotalNum(); jg++) {
|
||||
|
||||
if(ibox == 0 && ig == jg) continue; // exclude itself
|
||||
SingleParticlePos_t nncell(basegrid.Node[jg].Ri[0]+displ[0],
|
||||
basegrid.Node[jg].Ri[1]+displ[1],
|
||||
basegrid.Node[jg].Ri[2]+displ[2]);
|
||||
SingleParticlePos_t dcell = nncell-org;
|
||||
int icx = int(fabs(dcell[0]*dx[0]));
|
||||
int icy = int(fabs(dcell[1]*dx[1]));
|
||||
int icz = int(fabs(dcell[2]*dx[2]));
|
||||
bool connected = false;
|
||||
if(icx <= 1 && icy <= 1 && icz <= 1) {
|
||||
connected = true; // next cells are always included
|
||||
} else {
|
||||
if(Lattice.Dot(dcell,dcell) <= 4*RmaxSq) connected = true;
|
||||
}
|
||||
if(connected) {
|
||||
ID.push_back(jg);
|
||||
BC.push_back(Lattice.toCart(displ));
|
||||
nconnected++; // number of connected cells for a mesh
|
||||
}
|
||||
|
||||
}
|
||||
it++; ibox++;
|
||||
}
|
||||
maxnc = max(nconnected,maxnc);
|
||||
M[ig+1] = M[ig] + nconnected;
|
||||
}
|
||||
return maxnc; // return the maxmimum number of connected cells
|
||||
}
|
||||
*/
|
||||
void print(ostream& os) {
|
||||
for(int ig=0; ig<M.size()-1; ig++) {
|
||||
cout << ig << " has neighboring cell " << M[ig+1]-M[ig]<< endl;
|
||||
for(int ii=M[ig]; ii<M[ig+1]; ii++) {
|
||||
cout << ID[ii] << " " << BC[ii] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,265 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_UNIFORMGRIDLAYOUT_H
|
||||
#define OHMMS_UNIFORMGRIDLAYOUT_H
|
||||
|
||||
#include "Lattice/CrystalLattice.h"
|
||||
#include "Lattice/UniformCartesianGrid.h"
|
||||
#include <iostream>
|
||||
|
||||
/**@file UniformGridLayout.h
|
||||
*@brief Declaration of UniformGridLayout<T,D>
|
||||
*/
|
||||
|
||||
/** generic UniformGridLayout. Do nothing.
|
||||
*/
|
||||
template<class T, unsigned D>
|
||||
struct UniformGridLayout: public CrystalLattice<T,D>,
|
||||
public UniformCartesianGrid<T,D>{ };
|
||||
|
||||
/** specialization of UniformGridLayout<T,3> for 3-Dim layout
|
||||
*
|
||||
*This class represents a supercell and is one of the layout classes
|
||||
*to define a trait class PT for ParticleBase<PT> (as a matter of fact,
|
||||
*the only layout class implemented in ohmms).
|
||||
*
|
||||
*It is inherited from CrystalLattice<T,3> and
|
||||
*UniformCartesianGrid<T,3>: CrystalLattice defines a general
|
||||
*supercell and UniformCartesianGrid defines a cubic-cell view of a
|
||||
*general supercell. This layout class is intended for typical
|
||||
*condensed matter or molecular systems, where a uniform grid partition
|
||||
*works fairly well.
|
||||
*
|
||||
*The additional interfaces of UniformGridLayout class are primarily
|
||||
*for NNEngine classes, which use the parition information to evaluate
|
||||
*the neighbor lists efficiently.
|
||||
*
|
||||
*/
|
||||
template<class T>
|
||||
class UniformGridLayout<T,3>: public CrystalLattice<T,3>,
|
||||
public UniformCartesianGrid<T,3>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**enumeration for grid levels*/
|
||||
enum {MPI_GRID = 0, /*!< mpi level */
|
||||
OMP_GRID, /*!< open mp level */
|
||||
SPATIAL_GRID, /*!< spatial level */
|
||||
GridLevel = 3 /*!< counter used to tell the number of levels */
|
||||
};
|
||||
|
||||
typedef CrystalLattice<T,3> Base_t;
|
||||
typedef UniformCartesianGrid<T,3> Grid_t;
|
||||
typedef UniformGridLayout<T,3> This_t;
|
||||
|
||||
typedef typename Base_t::SingleParticlePos_t SingleParticlePos_t;
|
||||
typedef typename Base_t::SingleParticleIndex_t SingleParticleIndex_t;
|
||||
|
||||
/**default constructor
|
||||
*
|
||||
*Create 1x1x1 cubic view for a supercell assuming that no
|
||||
*parallelization is used.
|
||||
*/
|
||||
inline UniformGridLayout(){
|
||||
for(int i=0; i<GridLevel; i++) Grid[i] = SingleParticleIndex_t(1);
|
||||
SuperGrid.reserve(GridLevel);
|
||||
for(int i=0; i<GridLevel; i++) SuperGrid.push_back(NULL);
|
||||
}
|
||||
|
||||
|
||||
inline ~UniformGridLayout(){
|
||||
for(int i=0; i<SuperGrid.size(); i++)
|
||||
if(SuperGrid[i]) delete SuperGrid[i];
|
||||
}
|
||||
|
||||
///return the first cell connected to the ig cell
|
||||
inline int first_connected(int ig) const { return c_offset[ig];}
|
||||
|
||||
///return the last cell connected to the ig cell
|
||||
inline int last_connected(int ig) const { return c_offset[ig+1];}
|
||||
|
||||
/// return the cell index
|
||||
inline int id_connected(int j) const { return c_id[j];}
|
||||
|
||||
/// return the correction vector according to the boundary conditions
|
||||
inline SingleParticlePos_t bc(int j) const { return c_bc[j];}
|
||||
|
||||
/// return the total number of paritions
|
||||
inline int ncontexts() const { return c_offset.size()-1;}
|
||||
|
||||
/// return the maximum number of connected cells
|
||||
int connectGrid(T rmax);
|
||||
|
||||
template<class GIM>
|
||||
inline void makeGrid(const GIM& mgrid) {
|
||||
if(mgrid.size() < GridLevel) {
|
||||
Grid[SPATIAL_GRID] = mgrid.back();
|
||||
} else {
|
||||
for(int ig=0; ig<GridLevel; ig++) Grid[ig] = mgrid[ig];
|
||||
}
|
||||
///first build the spatial grid
|
||||
setGrid(Grid[SPATIAL_GRID]);
|
||||
}
|
||||
|
||||
inline Grid_t* restrict
|
||||
addGrid(int glevel, const SingleParticleIndex_t& agrid) {
|
||||
if(SuperGrid[glevel]) {
|
||||
SuperGrid[glevel]->setGrid(agrid);
|
||||
return SuperGrid[glevel];
|
||||
} else {
|
||||
Grid_t* g = new Grid_t(agrid);
|
||||
SuperGrid[glevel] = g;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
inline Grid_t* restrict getGrid(int glevel) { return SuperGrid[glevel];}
|
||||
inline const Grid_t* restrict getGrid(int glevel) const {
|
||||
return SuperGrid[glevel];
|
||||
}
|
||||
|
||||
inline int ngrid(int ig) const { return Grid[SPATIAL_GRID][ig];}
|
||||
inline int ngrid(int glevel, int ig) const { return Grid[glevel][ig];}
|
||||
void print(std::ostream& os) const;
|
||||
|
||||
inline void update() {
|
||||
for(int i=0; i<u_bc.size(); i++) c_bc.push_back(u_bc[i]);
|
||||
}
|
||||
|
||||
/** set the lattice vector with a tensor
|
||||
*@param lat a tensor representing a supercell
|
||||
*
|
||||
*In addition to setting the internal parameters, it updates the Cartesian displacement vectors.
|
||||
*/
|
||||
inline void update(const Tensor<T,3>& lat) {
|
||||
CrystalLattice<T,3>::set(lat);
|
||||
for(int i=0; i<u_bc.size(); i++) c_bc.push_back(u_bc[i]);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
///Uniform grid partitions at MPI_GRID, OPENMP_GRID, and SPATIAL_GRID levels.
|
||||
SingleParticleIndex_t Grid[GridLevel];
|
||||
|
||||
///UniformCartesianGrid for multi levels.
|
||||
std::vector<Grid_t*> SuperGrid;
|
||||
///offsets to determine cell conection
|
||||
std::vector<int> c_offset;
|
||||
///cell index connected to each cell
|
||||
std::vector<int> c_id;
|
||||
///displacement vectors due to the boundary conditions
|
||||
std::vector<SingleParticlePos_t> c_bc;
|
||||
///displacement vectors due to the boundary conditions in the unit-cell unit
|
||||
std::vector<SingleParticlePos_t> u_bc;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
int
|
||||
UniformGridLayout<T,3>::connectGrid(T rmax) {
|
||||
|
||||
///create the spatial grid
|
||||
setGrid(Grid[SPATIAL_GRID]);
|
||||
|
||||
SingleParticlePos_t u0(Delta[0],0.0,0.0);
|
||||
SingleParticlePos_t u1(0.0,Delta[1],0.0);
|
||||
SingleParticlePos_t u2(0.0,0.0,Delta[2]);
|
||||
T RmaxSq = rmax*rmax;
|
||||
|
||||
///calculate the extend of linked cells
|
||||
int nx = static_cast<int>(sqrt(RmaxSq/Dot(u0,u0)))+1;
|
||||
int ny = static_cast<int>(sqrt(RmaxSq/Dot(u1,u1)))+1;
|
||||
int nz = static_cast<int>(sqrt(RmaxSq/Dot(u2,u2)))+1;
|
||||
|
||||
|
||||
c_offset.resize(NumGrids+1);
|
||||
int ntot = NumGrids*(2*nx+1)*(2*ny+1)*(2*nz+1);
|
||||
if(c_id.capacity() < ntot) c_id.reserve(ntot);
|
||||
if(c_bc.capacity() < ntot) c_bc.reserve(ntot);
|
||||
if(u_bc.capacity() < ntot) u_bc.reserve(ntot);
|
||||
|
||||
int maxnc = 0, gtot = 0;
|
||||
SingleParticlePos_t dx(Delta[0],Delta[1],Delta[2]),org,d;
|
||||
c_offset[0] = 0;
|
||||
for(int ig=0; ig<NP[0]; ig++) {
|
||||
org[0] = (static_cast<T>(ig)+0.5)*Delta[0];
|
||||
for(int jg=0; jg<NP[1]; jg++) {
|
||||
org[1] = (static_cast<T>(jg)+0.5)*Delta[1];
|
||||
for(int kg=0; kg<NP[2]; kg++) {
|
||||
org[2] = (static_cast<T>(kg)+0.5)*Delta[2];
|
||||
T x,y,z;
|
||||
int nconnected = 0;
|
||||
for(int ix=-nx; ix<=nx; ix++) {
|
||||
d[0] = x = org[0]+T(ix)*dx[0];
|
||||
if(BoxBConds[0]) {
|
||||
x = fmod(d[0],1.0);
|
||||
if(x<0.0) x += 1.0;
|
||||
}
|
||||
if(x<0 || x>=1) continue;
|
||||
d[0] -= x;
|
||||
for(int jx=-ny; jx<=ny; jx++) {
|
||||
d[1] = y = org[1]+T(jx)*dx[1];
|
||||
if(BoxBConds[1]) {
|
||||
y = fmod(d[1],1.0); if(y<0) y += 1.0;
|
||||
}
|
||||
if(y<0 || y>=1) continue;
|
||||
d[1] -= y;
|
||||
for(int kx=-nz; kx<=nz; kx++) {
|
||||
d[2] = z = org[2]+T(kx)*dx[2];
|
||||
if(BoxBConds[2]) {
|
||||
z = fmod(d[2],1.0); if(z<0) z += 1.0;
|
||||
}
|
||||
if(z<0 || z>=1) continue;
|
||||
d[2] -= z;
|
||||
int iloc = loc(x,y,z);
|
||||
if(iloc == gtot && ix == 0 && jx == 0 && kx == 0) continue;
|
||||
c_id.push_back(iloc);
|
||||
u_bc.push_back(d);
|
||||
c_bc.push_back(toCart(d));
|
||||
nconnected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
c_offset[gtot+1] = c_offset[gtot]+nconnected; gtot++;
|
||||
maxnc = max(maxnc,nconnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxnc; // return the maxmimum number of connected cells
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void UniformGridLayout<T,3>::print(std::ostream& os) const {
|
||||
Base_t::print(os);
|
||||
printGrid(os);
|
||||
for(int ig=0; ig<c_offset.size()-1; ig++) {
|
||||
os << ig << " has neighboring cell "
|
||||
<< c_offset[ig+1]-c_offset[ig]<< std::endl;
|
||||
for(int ii=c_offset[ig]; ii<c_offset[ig+1]; ii++) {
|
||||
os << c_id[ii] << " " << c_bc[ii] << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,49 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#include "Message/CommCreate.h"
|
||||
|
||||
// initialize static data members
|
||||
|
||||
int TagMaker::CurrentTag = 1000;
|
||||
|
||||
Communicate* CommCreate::Comm =0;
|
||||
|
||||
Communicate* CommCreate::get() {
|
||||
if(!Comm) {
|
||||
Comm = new Communicate;
|
||||
}
|
||||
return Comm;
|
||||
}
|
||||
|
||||
Communicate* CommCreate::get(int argc, char **argv) {
|
||||
if(!Comm) {
|
||||
Comm = new Communicate(argc,argv);
|
||||
}
|
||||
return Comm;
|
||||
}
|
||||
|
||||
void CommCreate::remove() {
|
||||
if(Comm) delete Comm;
|
||||
Comm = 0;
|
||||
}
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,50 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef OHMMS_COMMCREATE_H
|
||||
#define OHMMS_COMMCREATE_H
|
||||
|
||||
#include "Message/TagMaker.h"
|
||||
#include "Message/Communicate.h"
|
||||
#ifdef USE_MPI
|
||||
#include <mpi.h>
|
||||
#endif
|
||||
|
||||
/*!\class CommCreate
|
||||
* \brief Singleton Pattern to create one instance of Communicate
|
||||
* during a run.
|
||||
*/
|
||||
class CommCreate {
|
||||
public:
|
||||
|
||||
static Communicate* get();
|
||||
static Communicate* get(int, char**);
|
||||
static void remove();
|
||||
|
||||
private:
|
||||
// factory
|
||||
CommCreate() { }
|
||||
~CommCreate() { }
|
||||
static Communicate* Comm;
|
||||
};
|
||||
#endif // OHMMS_COMMCREATE_H
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,100 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#include "Message/Communicate.h"
|
||||
#include "Message/TagMaker.h"
|
||||
|
||||
//static data of TagMaker::CurrentTag is initialized.
|
||||
int TagMaker::CurrentTag = 1000;
|
||||
|
||||
//Global Communicator is created without initialization
|
||||
Communicate* OHMMS::Controller = new Communicate;
|
||||
|
||||
//default constructor: ready for a serial execution
|
||||
Communicate::Communicate():d_mycontext(0), d_ncontexts(1), CommID(0){}
|
||||
|
||||
Communicate::Communicate(int argc, char **argv){
|
||||
initialize(argc,argv);
|
||||
}
|
||||
|
||||
//exclusive: OOMPI, MPI or Serial
|
||||
#ifdef USE_OOMPI
|
||||
|
||||
//================================================================
|
||||
// Implements Communicate with OOMPI library
|
||||
//================================================================
|
||||
#include "oompi.h"
|
||||
|
||||
Communicate::~Communicate(){ }
|
||||
|
||||
void Communicate::initialize(int argc, char **argv){
|
||||
OOMPI_COMM_WORLD.Init(argc, argv);
|
||||
d_mycontext = OOMPI_COMM_WORLD.Rank();
|
||||
d_ncontexts = OOMPI_COMM_WORLD.Size();
|
||||
CommID = OOMPI_COMM_WORLD.Get_mpi();
|
||||
}
|
||||
|
||||
void Communicate::finalize() {
|
||||
OOMPI_COMM_WORLD.Finalize();
|
||||
}
|
||||
|
||||
void Communicate::cleanupMessage(void*) { }
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_MPI
|
||||
|
||||
//================================================================
|
||||
// Implements Communicate with standard MPI library
|
||||
//================================================================
|
||||
#include <mpi.h>
|
||||
Communicate::~Communicate(){ }
|
||||
|
||||
void Communicate::initialize(int argc, char **argv){
|
||||
int flag;
|
||||
MPI_Initialized(&flag);
|
||||
if(!flag) {
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&d_ncontexts);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&d_mycontext);
|
||||
CommID = MPI_COMM_WORLD;
|
||||
}
|
||||
}
|
||||
|
||||
void Communicate::finalize(){
|
||||
MPI_Finalize();
|
||||
}
|
||||
|
||||
void Communicate::cleanupMessage(void*) { }
|
||||
|
||||
#else //USE_MPI
|
||||
|
||||
Communicate::~Communicate(){}
|
||||
void Communicate::initialize(int argc, char **argv){ }
|
||||
void Communicate::finalize(){ }
|
||||
void Communicate::cleanupMessage(void*) { }
|
||||
|
||||
#endif // !USE_MPI
|
||||
|
||||
#endif // !USE_OOMPI
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,84 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef OHMMS_COMMUNICATE_H
|
||||
#define OHMMS_COMMUNICATE_H
|
||||
|
||||
/**@class Communicate
|
||||
* @ingroup Message
|
||||
* @brief
|
||||
* Wrapping information on parallelism.
|
||||
* Very limited in functions. Currently, only single-mode or mpi-mode
|
||||
* is available (mutually exclusive).
|
||||
* @todo Possibly, make it a general manager class for mpi+openmp, mpi+mpi
|
||||
*/
|
||||
class Communicate {
|
||||
public:
|
||||
|
||||
///constructor
|
||||
Communicate();
|
||||
|
||||
///constructor with arguments
|
||||
Communicate(int argc, char **argv);
|
||||
|
||||
/**destructor
|
||||
* Call proper finalization of Communication library
|
||||
*/
|
||||
virtual ~Communicate();
|
||||
|
||||
void initialize(int argc, char **argv);
|
||||
void finalize();
|
||||
|
||||
///return the Communicator ID (typically MPI_WORLD_COMM)
|
||||
inline int getID() const { return CommID;}
|
||||
|
||||
|
||||
///return the rank of this node
|
||||
inline int getNodeID() const { return d_mycontext;}
|
||||
inline int mycontext() const { return d_mycontext;}
|
||||
|
||||
///return the number of nodes
|
||||
inline int getNumNodes() const { return d_ncontexts;}
|
||||
inline int ncontexts() const { return d_ncontexts;}
|
||||
|
||||
inline bool master() const { return (d_mycontext == 0);}
|
||||
|
||||
void cleanupMessage(void*);
|
||||
inline void setNodeID(int i) { d_mycontext = i;}
|
||||
inline void setCommID(int i) { CommID = i;}
|
||||
|
||||
protected:
|
||||
|
||||
int CommID;
|
||||
int d_mycontext;
|
||||
int d_ncontexts;
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace OHMMS {
|
||||
/** Global Communicator for a process
|
||||
*/
|
||||
extern Communicate* Controller;
|
||||
}
|
||||
#endif // OHMMS_COMMUNICATE_H
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,7 @@
|
|||
$(ODIR)/Communicate.o: $(OHMMSDIR)/src/Message/Communicate.cpp
|
||||
$(CXX) $(CXXFLAGSAPP) $(OHMMSINC) -c \
|
||||
$(OHMMSDIR)/src/Message/Communicate.cpp -o $(ODIR)/Communicate.o
|
||||
$(ODIR)/CommCreate.o: $(OHMMSDIR)/src/Message/CommCreate.cpp
|
||||
$(CXX) $(CXXFLAGSAPP) $(OHMMSINC) -c \
|
||||
$(OHMMSDIR)/src/Message/CommCreate.cpp -o $(ODIR)/CommCreate.o
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef OHMMS_OPENMP_H
|
||||
#define OHMMS_OPENMP_H
|
||||
#if defined(USE_OPENMP)
|
||||
#include <omp.h>
|
||||
#else
|
||||
inline int omp_get_thread_num() { return 0;}
|
||||
#endif
|
||||
#endif // OHMMS_COMMUNICATE_H
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,307 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
#include <mpi.h>
|
||||
#include "Message/ReplicaControl.h"
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
}
|
||||
|
||||
ReplicaControl::ReplicaControl() {
|
||||
//MPI_Init(&argc,&argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&NumReplica);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&ReplicaID);
|
||||
TotMD_t = 0.0e0;
|
||||
TotHMD_t = 0.0e0;
|
||||
}
|
||||
|
||||
|
||||
ReplicaControl::ReplicaControl(int argc, char **argv) {
|
||||
//MPI_Init(&argc,&argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&NumReplica);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&ReplicaID);
|
||||
TotMD_t = 0.0e0;
|
||||
TotHMD_t = 0.0e0;
|
||||
}
|
||||
|
||||
void resize(int n) {
|
||||
if(WallClockTime.size() < n) {
|
||||
WallClockTime.erase(WallClockTime.begin(), WallClockTime.end());
|
||||
MDTime.erase(MDTime.begin(), MDTime.end());
|
||||
HMDTime.erase(HMDTime.begin(), HMDTime.end());
|
||||
|
||||
WallClockTime = vector<double>(2*n,0.0e0);
|
||||
MDTime = vector<double>(2*n,0.0e0);
|
||||
HMDTime = vector<double>(2*n,0.0e0);
|
||||
}
|
||||
}
|
||||
|
||||
ReplicaControl::~ReplicaControl() {
|
||||
}
|
||||
|
||||
bool
|
||||
ReplicaControl::send(ParticlePos_t& p, int node, int btag, bool bcast){
|
||||
if(bcast) { // broadcasting positions to all the nodes
|
||||
int size = OHMMS_DIM*newp.size();
|
||||
int ierr = MPI_Bcast(&p[0][0], size, MPI_DOUBLE, ReplicaID, btag,
|
||||
MPI_COMM_WORLD);
|
||||
return true;
|
||||
} else {
|
||||
if(node < 0) return true; // do nothing
|
||||
MPI_Request request;
|
||||
int size = OHMMS_DIM*p.size();
|
||||
int errstat = MPI_Isend(&p[0][0], size, MPI_DOUBLE, node, btag,
|
||||
MPI_COMM_WORLD, &request);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ReplicaControl::recv(ParticlePos_t& p, int& node, int btag) {
|
||||
{
|
||||
int size = OHMMS_DIM*p.size();
|
||||
MPI_Request request;
|
||||
MPI_Status status;
|
||||
MPI_Irecv(&p[0][0], size, node, btag, MPI_COMM_WORLD, &request);
|
||||
bool flag = false;
|
||||
while (!flag) {
|
||||
MPI_Test(&request, &flag, &status);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplicaControl::sendDirections(int& inode){
|
||||
|
||||
int msg[2];
|
||||
if(inode < 0) {
|
||||
msg[0] = PARMD::finalize_tag;
|
||||
MPI_Bcast(&msg[0], 1, MPI_INT, ReplicaID,PARMD::command_tag,MPI_COMM_WORLD);
|
||||
return true;
|
||||
}
|
||||
|
||||
MPI_Request request;
|
||||
MPI_Status status;
|
||||
|
||||
msg[0] = PARMD::winner_tag;
|
||||
msg[1] = PARMD::losers_tag;
|
||||
|
||||
bool flag = false;
|
||||
for(int i=1; i<NumReplica; i++) {
|
||||
if(i == inode) {
|
||||
MPI_Isend(&msg[0],1,MPI_INT,i,PARMD::command_tag,
|
||||
MPI_COMM_WORLD, &request);
|
||||
} else {
|
||||
MPI_Isend(&msg[1],1,MPI_INT,i,PARMD::command_tag,
|
||||
MPI_COMM_WORLD, &request);
|
||||
}
|
||||
flag = false;
|
||||
while (!flag) {
|
||||
MPI_Test(&request, &flag, &status);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int ReplicaControl::recvDirections() {
|
||||
|
||||
int whattodo;
|
||||
|
||||
MPI_Request request;
|
||||
MPI_Status status;
|
||||
|
||||
MPI_Irecv(&whattodo, 1, MPI_INT, 0, PARMD::command_tag,
|
||||
MPI_COMM_WORLD, &request);
|
||||
|
||||
bool flag = false;
|
||||
while (!flag) {
|
||||
MPI_Test(&request, &flag, &status);
|
||||
}
|
||||
|
||||
return whatodo;
|
||||
}
|
||||
|
||||
bool ReplicaControl::reportTransition(double drsq){ //slaves
|
||||
double newdata[2];
|
||||
MPI_Request request;
|
||||
|
||||
newdata[0] = WallClockTime[FrameNum];
|
||||
newdata[1] = drsq;
|
||||
MPI_Isend(newdata,2,MPI_DOUBLE,0,PARMD::transition, MPI_COMM_WORLD, &request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReplicaControl::catchTransition(int& remNode, double& wallt, double& rsqmax){ // master
|
||||
|
||||
double newdata[2];
|
||||
static MPI_Request request;
|
||||
static MPI_Status status;
|
||||
static bool flag = true;
|
||||
|
||||
remNode = -1;
|
||||
|
||||
if(flag) { // initiate recv
|
||||
DEBUGMSG("Open a channel to catch the transition\n");
|
||||
MPI_Irecv(newdata, 2, MPI_INT, MPI_ANY_SOURCE,
|
||||
PARMD::transition_tag, MPI_COMM_WORLD, &request);
|
||||
flag = false;
|
||||
}
|
||||
|
||||
MPI_Test(&request, &flag, &status);
|
||||
if(flag) { // a transition is reported
|
||||
wallt = newdata[0];
|
||||
rsqmax = newdata[1];
|
||||
remNode = status.MPI_SOURCE; // copy the remote node
|
||||
}
|
||||
}
|
||||
|
||||
bool ReplicaControl::sendTransitionTime(double t0){
|
||||
|
||||
MPI_Bcast(&t0, 1, MPI_DOUBLE, ReplicaID, PARMD::stop_tag, MPI_COMM_WORLD);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplicaControl::recvTransitionTime(double& t0) {
|
||||
|
||||
double trecv = 0;
|
||||
|
||||
MPI_Status status;
|
||||
MPI_Recv(&trecv, 1, MPI_DOUBLE, 0, PARMD::stop_tag, MPI_COMM_WORLD, &status);
|
||||
|
||||
t0 = trecv;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplicaControl::sendExactTime(double wallt, bool havewon) {
|
||||
|
||||
int masternode = 0;
|
||||
double newtime[3];// vector<double> newtime(3);
|
||||
|
||||
if(havewon) {
|
||||
newtime[0] = MDTime[FrameNum];
|
||||
newtime[1] = WallClockTime[FrameNum];
|
||||
} else {
|
||||
int iframe=FrameNum;
|
||||
while(WallClockTime[iframe] >= wallt && iframe > 0){
|
||||
iframe--;
|
||||
}
|
||||
newtime[0] = MDTime[iframe];
|
||||
newtime[1] = WallClockTime[iframe];
|
||||
}
|
||||
|
||||
MPI_Request request;
|
||||
MPI_Isend(newtime,3,MPI_DOUBLE,0,PARMD::exacttime_tag, MPI_COMM_WORLD, &request);
|
||||
}
|
||||
|
||||
void ReplicaControl::collectExactTimes(int itrans, double t0) {
|
||||
|
||||
MPI_Status status;
|
||||
MPI_Request request;
|
||||
|
||||
int btag = PARMD::exacttime_tag;
|
||||
int numrecvd = NumReplica-1;
|
||||
double newtime[3];
|
||||
bool flag;
|
||||
|
||||
CumMD_t = t0; // constant time to be added to a new cumm. time
|
||||
|
||||
while(numrecvd > 0) {
|
||||
|
||||
MPI_Irecv(newtime, 3, MPI_DOUBLE, MPI_ANY_SOURCE,
|
||||
PARMD::exacttime_tag, MPI_COMM_WORLD, &request);
|
||||
flag = false;
|
||||
while(!false) {MPI_Test(&request, &flag, &status);}
|
||||
CumMD_t += newtime[0];
|
||||
numrecvd--;
|
||||
}
|
||||
MDTime[itrans] = CumMD_t;
|
||||
TotMD_t += CumMD_t;
|
||||
}
|
||||
|
||||
void ReplicaControl::reportTimeData(ostream& os,int i_trans){
|
||||
os << setw(18) << MDTime[i_trans] << setw(18) << TotMD_t << " ";
|
||||
}
|
||||
|
||||
// bool ReplicaControl::sendNewConfig(ParticlePos_t& newp){
|
||||
// int size = OHMMS_DIM*newp.size();
|
||||
// MPI_Bcast(&newp[0][0], size, MPI_DOUBLE, ReplicaID, PARMD_newconfig_tag,
|
||||
// MPI_COMM_WORLD);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// void ReplicaControl::recvNewConfig(ParticlePos_t& newp){
|
||||
|
||||
// int btag = PARMD_newconfig_tag;
|
||||
// int size = OHMMS_DIM*newp.size();
|
||||
|
||||
// MPI_Request request;
|
||||
// MPI_Status status;
|
||||
|
||||
// int masternode = 0;
|
||||
// MPI_Irecv(&newp[0][0], size, masternode, btag, MPI_COMM_WORLD, &request);
|
||||
|
||||
// bool flag = false;
|
||||
// while (!flag) {
|
||||
// MPI_Test(&request, &flag, &status);
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool ReplicaControl::sendMinConfig(ParticlePos_t& minp) {
|
||||
|
||||
// MPI_Request request;
|
||||
// MPI_Status status;
|
||||
// int size = OHMMS_DIM*newp.size();
|
||||
// int errstat = MPI_Isend(&minp[0][0], size, MPI_DOUBLE, 0, PARMD_minconfig_tag,
|
||||
// MPI_COMM_WORLD, &request);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// void ReplicaControl::recvMinConfig(ParticlePos_t& minp, int& inode) {
|
||||
|
||||
// int btag = PARMD_minconfig_tag;
|
||||
// int size = OHMMS_DIM*newp.size();
|
||||
|
||||
// MPI_Request request;
|
||||
// MPI_Status status;
|
||||
|
||||
// MPI_Irecv(&newp[0][0], size, inode, btag, MPI_COMM_WORLD, &request);
|
||||
|
||||
// bool flag = false;
|
||||
// while (!flag) {
|
||||
// MPI_Test(&request, &flag, &status);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void ReplicaControl::makeNodeConnection(const char *opt) {
|
||||
// if(!strcmp(opt,"chain")) {
|
||||
// RightNode =ReplicaID+1;
|
||||
// LeftNode = RightNode-2;
|
||||
// if(RightNode == NumReplica) RightNode = -1; // not periodic
|
||||
// }
|
||||
// }
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,133 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ReplicaControl using MPI
|
||||
// Responsible for book keeping for parallel replica with or without hmd
|
||||
// Using timer routines of Parmd7, Art Voter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OHMMS_REPLICACONTROL_H
|
||||
#define OHMMS_REPLICACONTROL_H
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
#include "Particle/OhmmsParticle.h"
|
||||
#include "Message/Communicate.h"
|
||||
|
||||
namespace PARMD {
|
||||
const int transition_tag = 10;
|
||||
const int exacttime_tag = 11;
|
||||
const int newconfig_tag = 12;
|
||||
const int minconfig_tag = 13;
|
||||
const int command_tag = 14;
|
||||
const int stop_tag = 15;
|
||||
const int pluscycle_tag = 16;
|
||||
const int minuscycle_tag = 17;
|
||||
const int winner_tag = 1;
|
||||
const int losers_tag = 0;
|
||||
const int noevent_tag = -1;
|
||||
const int finalize_tag = 99;
|
||||
}
|
||||
|
||||
class ReplicaControl {
|
||||
|
||||
public:
|
||||
|
||||
typedef OHMMS::Particle_t::ParticlePos_t ParticlePos_t;
|
||||
enum ReplicaTags { NEWPOS, CUMTIME, TRANSITION};
|
||||
|
||||
//Communicate* OhmmsComm;
|
||||
|
||||
ReplicaControl();
|
||||
ReplicaControl(int, char**);
|
||||
~ReplicaControl();
|
||||
|
||||
void init(int nproc); // number of processors to
|
||||
inline int getNumNodes() const {OhmmsComm->getNumNodes();}
|
||||
inline int getNodeID() const {OhmmsComm->getNodeID();}
|
||||
inline bool master() const { return OhmmsComm->master();}
|
||||
|
||||
// Time-related funtions
|
||||
inline void saveMDTime(double nowT, double wallt, int iframe){
|
||||
FrameNum = iframe; // match the frame index
|
||||
WallClockTime[FrameNum] = wallt;
|
||||
MDTime[FrameNum] = nowT;
|
||||
}
|
||||
|
||||
inline double getWallClockTime() { return WallClockTime[FrameNum];}
|
||||
void resetTimer() { // for each transition, reset parameters
|
||||
FrameNum = 0;
|
||||
CumMD_t = 0.0e0;
|
||||
CumHMD_t = 0.0e0;
|
||||
}
|
||||
|
||||
bool send(const ParticlePos_t&, int node, int tag, bool bcast=false);
|
||||
bool recv(ParticlePos_t&, int& node, int tag);
|
||||
|
||||
// // send/recv of new configurations
|
||||
// bool sendNewConfig(ParticlePos_t& );
|
||||
// void recvNewConfig(ParticlePos_t& );
|
||||
|
||||
// // send/recv of a mininum configurations
|
||||
// bool sendMinConfig(ParticlePos_t& minp);
|
||||
// void recvMinConfig(ParticlePos_t& minp, int& inode);
|
||||
// bool sendNextNode(ParticlePos_t& , int );
|
||||
// bool recvNextNode(ParticlePos_t& , int );
|
||||
|
||||
// send/irecv of the transition time
|
||||
bool reportTransition(double);
|
||||
void catchTransition(int& inode, double&, double&);
|
||||
|
||||
// send transition time if a transition is detected
|
||||
// "the" master sends the first-in transition wall-clock time to slaves
|
||||
bool sendTransitionTime(double );
|
||||
bool recvTransitionTime(double&);
|
||||
|
||||
// sends MD time at the wall-clock time when the winner found a transition
|
||||
// "the" master collect MD times sent from all other nodes
|
||||
bool sendExactTime(double, bool havewon = false );
|
||||
void collectExactTimes(int itrans, double t0);
|
||||
|
||||
bool sendDirections(int& winner);
|
||||
int recvDirections();
|
||||
|
||||
void reportTimeData(ostream& ,int itrans);
|
||||
|
||||
void resize(int n);
|
||||
|
||||
protected:
|
||||
|
||||
int NumReplica;
|
||||
vector<int> ReplicaID;
|
||||
|
||||
double CumMD_t, CumHMD_t; // cummulative time over replica
|
||||
double TotMD_t, TotHMD_t; // total time
|
||||
int FrameNum;
|
||||
int LeftNode, RightNode;
|
||||
|
||||
vector<double> WallClockTime; // wall-clock time
|
||||
vector<double> MDTime; // mdtime
|
||||
vector<double> HMDTime; // hyper time will be added
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,123 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
#include "Message/ReplicaControl.h"
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
}
|
||||
|
||||
// instantiate the Communicator
|
||||
//Communicate* ReplicaControl::OhmmsComm = new Communicate;
|
||||
|
||||
ReplicaControl::ReplicaControl() {
|
||||
ReplicaID = vector<int>(1);
|
||||
NumReplica = OhmmsComm->getNumNodes();
|
||||
ReplicaID[0] = OhmmsComm->getNodeID();
|
||||
TotMD_t = 0.0e0;
|
||||
TotHMD_t = 0.0e0;
|
||||
|
||||
}
|
||||
|
||||
ReplicaControl::ReplicaControl(int argc, char **argv) {
|
||||
ReplicaID = vector<int>(1);
|
||||
NumReplica = OhmmsComm->getNumNodes();
|
||||
ReplicaID[0] = OhmmsComm->getNodeID();
|
||||
TotMD_t = 0.0e0;
|
||||
TotHMD_t = 0.0e0;
|
||||
}
|
||||
|
||||
void ReplicaControl::init(int nproc){
|
||||
if(nproc != ReplicaID.size()) {
|
||||
ReplicaID = vector<int>(nproc);
|
||||
for(int i=0; i<nproc; i++) ReplicaID[i] = i;
|
||||
}
|
||||
} // number of processors to
|
||||
|
||||
void ReplicaControl::resize(int n) {
|
||||
if(WallClockTime.size() < n) {
|
||||
WallClockTime.erase(WallClockTime.begin(), WallClockTime.end());
|
||||
MDTime.erase(MDTime.begin(), MDTime.end());
|
||||
HMDTime.erase(HMDTime.begin(), HMDTime.end());
|
||||
|
||||
WallClockTime = vector<double>(2*n,0.0e0);
|
||||
MDTime = vector<double>(2*n,0.0e0);
|
||||
HMDTime = vector<double>(2*n,0.0e0);
|
||||
}
|
||||
}
|
||||
|
||||
bool ReplicaControl::send(const ParticlePos_t& p, int node, int btag, bool bcast)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReplicaControl::recv(ParticlePos_t& p, int& node, int btag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ReplicaControl::sendDirections(int& inode){
|
||||
return true;
|
||||
}
|
||||
|
||||
int ReplicaControl::recvDirections() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ReplicaControl::reportTransition(double drsq){ //slaves
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReplicaControl::catchTransition(int& remNode, double& wallt, double& rsqmax){ // master
|
||||
|
||||
}
|
||||
|
||||
bool ReplicaControl::sendTransitionTime(double t0){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplicaControl::recvTransitionTime(double& t0) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplicaControl::sendExactTime(double wallt, bool havewon) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReplicaControl::collectExactTimes(int itrans, double t0) {
|
||||
|
||||
}
|
||||
|
||||
void ReplicaControl::reportTimeData(ostream& os,int i_trans){
|
||||
os << setw(18) << MDTime[i_trans] << setw(18) << TotMD_t << " ";
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,40 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef OHMMS_TAG_MAKER_H
|
||||
#define OHMMS_TAG_MAKER_H
|
||||
/*!\class TagMaker
|
||||
* \brief Assign a unique tag whenver TagMaker::TagMaker() is called.
|
||||
*/
|
||||
class TagMaker {
|
||||
public:
|
||||
|
||||
TagMaker(){ MyTag = (++CurrentTag);}
|
||||
~TagMaker() {}
|
||||
int operator()()const { return MyTag;}
|
||||
private:
|
||||
int MyTag;
|
||||
static int CurrentTag;
|
||||
};
|
||||
#endif // OHMMS_TAG_MAKER_H
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,137 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
#ifndef OHMMS_BLAS_FUNCTIONDEFS_H
|
||||
#define OHMMS_BLAS_FUNCTIONDEFS_H
|
||||
|
||||
#include <complex>
|
||||
using namespace std;
|
||||
|
||||
#ifdef ADD_
|
||||
#define daxpy daxpy_
|
||||
#define saxpy saxpy_
|
||||
#define zaxpy zaxpy_
|
||||
#define dnrm2 dnrm2_
|
||||
#define snrm2 snrm2_
|
||||
#define dznrm2 dznrm2_
|
||||
#define dsymv dsymv_
|
||||
#define ssymv ssymv_
|
||||
#define csymv csymv_
|
||||
#define zsymv zsymv_
|
||||
#define ddot ddot_
|
||||
#define sdot sdot_
|
||||
#define dscal dscal_
|
||||
#define dcopy dcopy_
|
||||
#define zcopy zcopy_
|
||||
#define dsyrk dsyrk_
|
||||
#define dsymm dsymm_
|
||||
#define dgemm dgemm_
|
||||
#define dsyr2k dsyr2k_
|
||||
#define dgetrf dgetrf_
|
||||
#define dgetri dgetri_
|
||||
#define zgetrf zgetrf_
|
||||
#define zgetri zgetri_
|
||||
#endif
|
||||
|
||||
// declaring Fortran interfaces
|
||||
extern "C" {
|
||||
|
||||
double ddot(const int& n, const double *dx, const int& incx, const double *dy, const int &incy);
|
||||
|
||||
float sdot(const int& n, const float *dx, const int& incx, const float *dy, const int &incy);
|
||||
|
||||
void daxpy(const int& n, const double& da,
|
||||
const double *dx, const int& incx, double *dy, const int& incy);
|
||||
|
||||
void saxpy(const int& n, const float& da,
|
||||
const float *dx, const int& incx, float *dy, const int& incy);
|
||||
|
||||
void zaxpy(const int& n, const complex<double>& da, const complex<double> *dx,
|
||||
const int& incx, complex<double> *dy, const int& incy);
|
||||
|
||||
|
||||
double dnrm2(const int& n, const double *dx, const int& incx);
|
||||
float snrm2(const int& n, const float *dx, const int& incx);
|
||||
double dznrm2(const int& n, const complex<double> *dx, const int& incx);
|
||||
|
||||
|
||||
double dscal(const int& n, const double&, double* x, const int&);
|
||||
|
||||
void dsymv(const char& uplo, const int& n, const double& alpha,
|
||||
const double& a, const int& lda, const double* x, const int& incx,
|
||||
const double& beta, double *y, const int& incy);
|
||||
|
||||
void ssymv(const char& uplo, const int& n, const float& alpha,
|
||||
const float& a, const int& lda,
|
||||
const float* x, const int& incx,
|
||||
const float& beta, float *y, const int& incy);
|
||||
|
||||
void zsymv(const char& uplo, const int& n, const complex<double>& alpha,
|
||||
complex<double>* a, const int& lda, complex<double>* x,
|
||||
const int& incx, const complex<double>& beta,
|
||||
complex<double> *y, const int& incy);
|
||||
|
||||
void csymv(const char& uplo, const int& n, const complex<float>& alpha,
|
||||
complex<float>* a, const int& lda, complex<float>* x,
|
||||
const int& incx, const complex<float>& beta,
|
||||
complex<float> *y, const int& incy);
|
||||
|
||||
void zcopy(const int& n, const complex<double>* x,
|
||||
const int& incx, complex<double>* y, const int& incy);
|
||||
void dcopy(const int& n, const double*, const int& , double *, const int&);
|
||||
|
||||
|
||||
void dsyr2k(const char&, const char&, const int&, const int&,
|
||||
const double&, const double*, const int&,
|
||||
const double*, const int&,
|
||||
const double&, double*, const int&);
|
||||
|
||||
void dsymm(const char&, const char&, const int&, const int&, const double&,
|
||||
const double* A, const int& lda,
|
||||
const double* B, const int& ldb,
|
||||
const double& beta, double* C, const int& ldc );
|
||||
|
||||
void dgemm(const char&, const char&,
|
||||
const int&, const int&, const int&,
|
||||
const double&, const double*, const int&, const double*, const int&,
|
||||
const double&, double*, const int&);
|
||||
|
||||
void dsyrk(const char&, const char&, const int&, const int&,
|
||||
const double&, const double*, const int&,
|
||||
const double&, double*,const int&);
|
||||
|
||||
void dgetrf(const int& n, const int& m, double* a, const int& n0,
|
||||
int* piv, int& st);
|
||||
|
||||
void zgetrf(const int& n, const int& m, complex<double>* a, const int& n0,
|
||||
int* piv, int& st);
|
||||
|
||||
void dgetri(const int& n, double* a, const int& n0,
|
||||
int* piv, double* work, const int&, int& st);
|
||||
|
||||
|
||||
void zgetri(const int& n, complex<double>* a, const int& n0,
|
||||
int* piv, complex<double>* work, const int&, int& st);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,118 @@
|
|||
// -*- C++ -*-
|
||||
/*! \author Jordan Vincent
|
||||
* \author Curry Taylor
|
||||
* \note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include "Numerics/Clebsch_Gordan.h"
|
||||
|
||||
/*!\fn Clebsch_Gordan::Clebsch_Gordan(const int lmax)
|
||||
* \param lmax the maximum angular momentum
|
||||
* \brief Constructs all the Clebsch-Gordan coefficients
|
||||
for \f$ 0 \le l_1 \le l_{max}, 0 \le l_2 \le l_1 \f$.
|
||||
This routine was adopted from a FORTRAN 77 algorithm taken
|
||||
from Rose's 'Elementary Theory of Angular Momentum', p. 39,
|
||||
Wigner's formula. The coefficients listed are only those
|
||||
for which \f$ l_1 \ge l_2 \f$, otherwise the relationship
|
||||
\f[ \langle l_1 m_1 l_2 m_2 | l_3 m_3 \rangle
|
||||
= (-1)^{l_1+l_2+l_3} \langle l_2 m_2 l_1 m_1 | l_3 m_3
|
||||
\rangle \f] applies.
|
||||
Coeffienents known to be zero (because of either the
|
||||
L or M selection rules) are not computed, and these should not
|
||||
be sought.
|
||||
* \note The indexing of the array is as follows:
|
||||
\f[ cg(l1,l2,l3,m1+Lmax,m2+Lmax) \f]
|
||||
this is due to the need to index arrays from 0 to N-1
|
||||
in C++.
|
||||
* \note As the main routine is statically defined (hard-coded),
|
||||
\f$ l \f$ values greater than 6 are not allowed and will cause
|
||||
error.
|
||||
*
|
||||
*/
|
||||
|
||||
Clebsch_Gordan::Clebsch_Gordan(const int lmax):Lmax(lmax){
|
||||
|
||||
int l1 = Lmax+1;
|
||||
int l2 = 2*Lmax+1;
|
||||
|
||||
cg.resize(l1,l1,l2,l2,l2);
|
||||
|
||||
// std::cout << cg.shape() << std::endl;
|
||||
|
||||
cg = 0.0;
|
||||
|
||||
build_coefficients();
|
||||
}
|
||||
|
||||
Clebsch_Gordan::~Clebsch_Gordan() { cg.free(); }
|
||||
|
||||
/*!
|
||||
* \fn void Clebsch_Gordan::build_coefficients()
|
||||
*
|
||||
* \brief Calculates the Clebsch-Gordan coefficients and stores
|
||||
them in a 5-dimensional Blitz++ array.
|
||||
*
|
||||
*/
|
||||
|
||||
void Clebsch_Gordan::build_coefficients() {
|
||||
|
||||
double si[33], fa[33], sum, prefactor;
|
||||
int lmin, i, l1, l2, l3, m1, m2, m3, nmin, nmax;
|
||||
|
||||
si[0] = 1.0;
|
||||
fa[0] = 1.0;
|
||||
|
||||
for(i=1; i<=32; i++) {
|
||||
si[i] = -si[i-1];
|
||||
fa[i] = (double)i * fa[i-1];
|
||||
}
|
||||
|
||||
for(l1=0; l1<=Lmax; l1++) {
|
||||
for(l2=0; l2<=l1; l2++) {
|
||||
for(m1=-l1; m1<=l1; m1++) {
|
||||
for(m2=-l2; m2<=l2; m2++) {
|
||||
m3 = m1 + m2;
|
||||
lmin = abs(l1-l2);
|
||||
|
||||
if(lmin < abs(m3)) { lmin = abs(m3); }
|
||||
|
||||
for(l3=lmin; l3<=l1+l2; l3++) {
|
||||
prefactor = 2.0*l3 + 1.0;
|
||||
prefactor *= fa[l3+l1-l2] / fa[l1+l2+l3+1];
|
||||
prefactor *= fa[l3-l1+l2] / fa[l1-m1];
|
||||
prefactor *= fa[l1+l2-l3] / fa[l1+m1];
|
||||
prefactor *= fa[l3+m3] / fa[l2-m2];
|
||||
prefactor *= fa[l3-m3] / fa[l2+m2];
|
||||
prefactor = sqrt(prefactor);
|
||||
|
||||
nmax = l3 - l1 + l2;
|
||||
if(l3+m3 < nmax) { nmax = l3+m3; }
|
||||
|
||||
nmin = 0;
|
||||
if(l1-l2-m3 < nmin) { nmin = -(l1-l2-m3); }
|
||||
|
||||
sum = 0;
|
||||
for(i=nmin; i<=nmax; i++) {
|
||||
sum += (si[i+l2+m2]/fa[i]) * fa[l2+l3+m1-i] * fa[l1-m1+i]
|
||||
/ fa[l3-l1+l2-i] / fa[l3+m3-i] / fa[i+l1-l2-m3];
|
||||
}
|
||||
|
||||
cg(l1,l2,l3,m1+Lmax,m2+Lmax) = prefactor*sum;
|
||||
cg(l2,l1,l3,m2+Lmax,m1+Lmax) = si[l1+l2+l3]*prefactor*sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// -*- C++ -*-
|
||||
/*! \author Jordan Vincent
|
||||
* \author Curry Taylor
|
||||
* \note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
#ifndef CLEBSCH_GORDAN_H2
|
||||
#define CLEBSCH_GORDAN_H2
|
||||
|
||||
#include <blitz/array.h>
|
||||
|
||||
/**class Clebsch_Gordan
|
||||
*\brief Calculates the Clebsch-Gordan coefficients
|
||||
*/
|
||||
class Clebsch_Gordan {
|
||||
public:
|
||||
|
||||
Clebsch_Gordan(const int lmax);
|
||||
///destructor
|
||||
~Clebsch_Gordan();
|
||||
|
||||
///maximum angular momentum
|
||||
int Lmax;
|
||||
///array to store the Clebsch-Gordan coefficients
|
||||
blitz::Array<double,5> cg;
|
||||
///returns \f$ \langle l_1 m_1 l_2 m_2 | l_3 (m_1+m_2) \rangle \f$
|
||||
inline double operator()(int l1, int l2, int l3, int m1, int m2) const {
|
||||
return cg(l1,l2,l3,m1+Lmax,m2+Lmax);
|
||||
}
|
||||
|
||||
private:
|
||||
/// default constructor not implemented
|
||||
Clebsch_Gordan() { }
|
||||
|
||||
void build_coefficients();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef OHMMS_CONSTSCALINGSKMODEL_H
|
||||
#define OHMMS_CONSTSCALINGSKMODEL_H
|
||||
|
||||
// SK<T,L1,L2,MID> where MID = 0 for no scaling
|
||||
// dum scaling function which returns a constant function
|
||||
struct ConstScale {
|
||||
double C;
|
||||
ConstScale(double c=1.0):C(c){ }
|
||||
~ConstScale() { }
|
||||
inline double operator()(double r) { return C;}
|
||||
inline double operator()(double r, double& vr) { vr = C/r; return 0.0e0;}
|
||||
inline double operator()(double r, double& vr, double& dvr) {
|
||||
vr = C/r/r; dvr = 0.0e0; return 0.0e0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* OHMMS_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,130 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_SINECOSINEFUNCTION_H
|
||||
#define OHMMS_SINECOSINEFUNCTION_H
|
||||
#include <math.h>
|
||||
|
||||
template<class T, class PT>
|
||||
struct Sine3D
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef PT pos_type;
|
||||
|
||||
Sine3D(value_type kx = 0, value_type ky =0, value_type kz = 0) {
|
||||
set(kx,ky,kz);
|
||||
}
|
||||
|
||||
void set(value_type kx, value_type ky, value_type kz) {
|
||||
const double twopi = 2.0*M_PI;
|
||||
Kx = twopi*(kx+0.5);
|
||||
Ky = twopi*(ky+0.5);
|
||||
Kz = twopi*(kz+0.5);
|
||||
Knorm2 = Kx*Kx+Ky*Ky+Kz*Kz;
|
||||
}
|
||||
|
||||
inline value_type evaluate(const PT& r) {
|
||||
return sin(Kx*r[0])*sin(Ky*r[1])*sin(Kz*r[2]);
|
||||
}
|
||||
|
||||
inline value_type evaluate(const PT& r, PT& gr, value_type& lap) {
|
||||
value_type v;
|
||||
gr = gradient(r,v);
|
||||
lap = -Knorm2*v;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
inline PT gradient(const PT& r, value_type& v) {
|
||||
v = evaluate(r);
|
||||
return PT(Kx*cos(Kx*r[0])*sin(Ky*r[1])*sin(Kz*r[2]),
|
||||
Ky*sin(Kx*r[0])*cos(Ky*r[1])*sin(Kz*r[2]),
|
||||
Kz*sin(Kx*r[0])*sin(Ky*r[1])*cos(Kz*r[2]));
|
||||
}
|
||||
|
||||
|
||||
// update internal variables and return the funcional value at r
|
||||
inline value_type laplacian(const PT& r) {
|
||||
Lap = laplacian(r,Val,Grad);
|
||||
return Val;
|
||||
}
|
||||
|
||||
inline value_type operator()(const PT& r) {
|
||||
return evaluate(r);
|
||||
}
|
||||
|
||||
value_type Kx, Ky, Kz, Knorm2;
|
||||
value_type Val, Lap;
|
||||
pos_type Grad;
|
||||
};
|
||||
|
||||
template<class T, class PT>
|
||||
struct Cosine3D
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef PT pos_type;
|
||||
|
||||
Cosine3D(value_type kx = 0, value_type ky =0, value_type kz = 0) {
|
||||
set(kx,ky,kz);
|
||||
}
|
||||
|
||||
void set(value_type kx, value_type ky, value_type kz) {
|
||||
const double twopi = 2.0*M_PI;
|
||||
Kx = twopi*(kx+0.5);
|
||||
Ky = twopi*(ky+0.5);
|
||||
Kz = twopi*(kz+0.5);
|
||||
Knorm2 = Kx*Kx+Ky*Ky+Kz*Kz;
|
||||
}
|
||||
|
||||
inline value_type evaluate(const PT& r) {
|
||||
return cos(Kx*r[0])*cos(Ky*r[1])*cos(Kz*r[2]);
|
||||
}
|
||||
|
||||
inline PT gradient(const PT& r, value_type& v) {
|
||||
v = evaluate(r);
|
||||
return PT(-Kx*sin(Kx*r[0])*cos(Ky*r[1])*cos(Kz*r[2]),
|
||||
-Ky*cos(Kx*r[0])*sin(Ky*r[1])*cos(Kz*r[2]),
|
||||
-Kz*cos(Kx*r[0])*cos(Ky*r[1])*sin(Kz*r[2]));
|
||||
}
|
||||
|
||||
inline value_type laplacian(const PT& r, value_type& v, PT& gr) {
|
||||
gr = gradient(r,v);
|
||||
return -Knorm2*v;
|
||||
}
|
||||
|
||||
// update internal variables
|
||||
inline value_type laplacian(const PT& r) {
|
||||
Lap = laplacian(r,Val,Grad);
|
||||
return Val;
|
||||
}
|
||||
|
||||
inline value_type operator()(const PT& r) {
|
||||
return evaluate(r);
|
||||
}
|
||||
|
||||
value_type Kx, Ky, Kz, Knorm2;
|
||||
value_type Val, Lap;
|
||||
pos_type Grad;
|
||||
};
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,307 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef CUBICSPLINE3D_REGULARGRID_H
|
||||
#define CUBICSPLINE3D_REGULARGRID_H
|
||||
|
||||
#include <bitset>
|
||||
using std::bitset;
|
||||
|
||||
/*! \class template<class T> CubicSplineDiff
|
||||
* \brief spline functions on regular grid [Rmin, Rmax)
|
||||
*/
|
||||
|
||||
template<class grid_type, class pos_type>
|
||||
class CubicSpline3D {
|
||||
public:
|
||||
|
||||
typedef typename grid_type::value_type value_type;
|
||||
pos_type Rmin, Rmax, dr, drinv, drinv2, dr2over6, drover6;
|
||||
bitset<4> xyz[8];
|
||||
grid_type Y;
|
||||
|
||||
//!< default constructor
|
||||
CubicSpline3D():Y(NULL){
|
||||
setxyz();
|
||||
}
|
||||
|
||||
//!< default constructor
|
||||
CubicSpline3D(const CubicSpline3D<grid_type,pos_type>& a) {
|
||||
setxyz();
|
||||
Rmin = a.Rmin;
|
||||
Rmax = a.Rmax;
|
||||
dr = a.dr;
|
||||
drinv = a.drinv;
|
||||
drover6 = a.drover6;
|
||||
dr2over6 = a.dr2over6;
|
||||
//Y = a.Y;
|
||||
}
|
||||
|
||||
void setxyz() {
|
||||
//4-bit to calculate the coefficient indices and sign
|
||||
//xyz[i](x,y,z,sign): initially, all the bits are set to 0
|
||||
//xyz[0] = bitset<4>(0,0,0,0); // -1(0) 3*0
|
||||
xyz[1].flip(2); xyz[1].flip(3); //xyz[1] = bitset<4>(0,0,1,1); // +1(1) 2*0
|
||||
xyz[2].flip(1); xyz[2].flip(2); //xyz[2] = bitset<4>(0,1,1,0); // -1(0) 1*0
|
||||
xyz[3].flip(1); xyz[3].flip(3); //xyz[3] = bitset<4>(0,1,0,1); // +1(1) 2*0
|
||||
xyz[4].flip(0); xyz[4].flip(3); //xyz[4] = bitset<4>(1,0,0,1); // +1(1) 2*0
|
||||
xyz[5].flip(0); xyz[5].flip(2); //xyz[5] = bitset<4>(1,0,1,0); // -1(0) 1*0
|
||||
xyz[6].flip(); //xyz[6] = bitset<4>(1,1,1,1); // +1(1) 0*0
|
||||
xyz[7].flip(0); xyz[7].flip(1); //xyz[7] = bitset<4>(1,1,0,0); // -1(0) 1*0
|
||||
}
|
||||
|
||||
value_type& operator()(int i, int j, int k) {
|
||||
// all shifted by 1 for the boundary
|
||||
return Y(i,j,k);
|
||||
}
|
||||
|
||||
value_type operator()(int i, int j, int k) const {
|
||||
// all shifted by 1 for the boundary
|
||||
return Y(i,j,k);
|
||||
}
|
||||
|
||||
//!< resize the arrays
|
||||
void resize(const int l, const int m, const int n) {
|
||||
Y.resize(l+1,m+1,n+1);
|
||||
Rmin[0] = 0.0; Rmin[1] = 0.0; Rmin[2] = 0.0;
|
||||
Rmax[0] = 1.0; Rmax[1] = 1.0; Rmax[2] = 1.0;
|
||||
drinv[0] = static_cast<value_type>(l);
|
||||
drinv[1] = static_cast<value_type>(m);
|
||||
drinv[2] = static_cast<value_type>(n);
|
||||
drinv2[0] = drinv[0]*drinv[0];
|
||||
drinv2[1] = drinv[1]*drinv[1];
|
||||
drinv2[2] = drinv[2]*drinv[2];
|
||||
dr[0] = 1.0/drinv[0];
|
||||
dr[1] = 1.0/drinv[1];
|
||||
dr[2] = 1.0/drinv[2];
|
||||
drover6[0] = dr[0]/6.0;
|
||||
drover6[1] = dr[1]/6.0;
|
||||
drover6[2] = dr[2]/6.0;
|
||||
dr2over6[0] = dr[0]*drover6[0];
|
||||
dr2over6[1] = dr[1]*drover6[1];
|
||||
dr2over6[2] = dr[2]*drover6[2];
|
||||
}
|
||||
|
||||
|
||||
value_type evaluate(const pos_type& pos) {
|
||||
|
||||
// find the location of pos
|
||||
value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// find the index of pos
|
||||
int im = static_cast<int>(di);
|
||||
int jm = static_cast<int>(dj);
|
||||
int km = static_cast<int>(dk);
|
||||
// find the index+1 of pos
|
||||
int ip = im+1;
|
||||
int jp = jm+1;
|
||||
int kp = km+1;
|
||||
|
||||
// determin L_{nx}, L_{ny}, L_{nz}
|
||||
//\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
pos_type Lm(static_cast<value_type>(im)-di,
|
||||
static_cast<value_type>(jm)-dj,
|
||||
static_cast<value_type>(km)-dk);
|
||||
|
||||
|
||||
// determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
//\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
// = -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
pos_type Lp = Lm + 1.0;
|
||||
|
||||
// determin C_{nx}, C_{ny}, C_{nz}
|
||||
pos_type Cm(dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1),
|
||||
dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1),
|
||||
dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1));
|
||||
|
||||
// determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
pos_type Cp(dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1),
|
||||
dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1),
|
||||
dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1));
|
||||
|
||||
int i, j, k;
|
||||
value_type Lx, Ly, Lz;
|
||||
value_type Cx, Cy, Cz;
|
||||
value_type y, y2x, y2y, y2z;
|
||||
value_type res = 0.0;
|
||||
// precalculate d^2 phi/dx^2, d^2 phi/dy^2 and d^2 phi/dz^2
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
|
||||
// get Lx, Cx, Cvx, and index i to get the value
|
||||
if(xyz[ixyz][0]) { // (1,y,z)
|
||||
Lx = Lp[0]; Cx = Cp[0]; i = im;
|
||||
}
|
||||
else { // (0,y,z)
|
||||
Lx = Lm[0]; Cx = Cm[0]; i = ip;
|
||||
}
|
||||
|
||||
// get Ly, Cy, Cvy, and index j to get the value
|
||||
if(xyz[ixyz][1]) { // (x,1,z)
|
||||
Ly = Lp[1]; Cy = Cp[1]; j = jm;
|
||||
}
|
||||
else { // (x,0,z)
|
||||
Ly = Lm[1]; Cy = Cm[1]; j = jp;
|
||||
}
|
||||
|
||||
// get Lz, Cz, Cvz, and index k to get the value
|
||||
if(xyz[ixyz][2]) { // (x,y,1)
|
||||
Lz = Lp[2]; Cz = Cp[2]; k = km;
|
||||
}
|
||||
else { // (x,y,0)
|
||||
Lz = Lm[2]; Cz = Cm[2]; k = kp;
|
||||
}
|
||||
|
||||
y = Y(i,j,k);
|
||||
|
||||
//\warning: not protected for negative indices
|
||||
y2x = (Y(i+1,j,k)+Y(i-1,j,k)-2.0*y)*drinv[0]*drinv[0];
|
||||
y2y = (Y(i,j+1,k)+Y(i,j-1,k)-2.0*y)*drinv[1]*drinv[1];
|
||||
y2z = (Y(i,j,k+1)+Y(i,j,k-1)-2.0*y)*drinv[2]*drinv[2];
|
||||
if(xyz[ixyz][3]) {//positive
|
||||
res += (Lx*Ly*Lz*y +Cx*Ly*Lz*y2x +Lx*Cy*Lz*y2y+Lx*Ly*Cz*y2z);
|
||||
} else {
|
||||
res -= (Lx*Ly*Lz*y +Cx*Ly*Lz*y2x +Lx*Cy*Lz*y2y+Lx*Ly*Cz*y2z);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
value_type laplacian(const pos_type& pos, value_type& value, pos_type& gr) {
|
||||
|
||||
// find the location of pos
|
||||
value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// find the index of pos
|
||||
int im = static_cast<int>(di);
|
||||
int jm = static_cast<int>(dj);
|
||||
int km = static_cast<int>(dk);
|
||||
|
||||
// find the index+1 of pos
|
||||
int ip = im+1;
|
||||
int jp = jm+1;
|
||||
int kp = km+1;
|
||||
|
||||
// determin L_{nx}, L_{ny}, L_{nz}
|
||||
//\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
pos_type Lm(static_cast<value_type>(im)-di,
|
||||
static_cast<value_type>(jm)-dj,
|
||||
static_cast<value_type>(km)-dk);
|
||||
|
||||
// determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
//\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
//= -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
pos_type Lp = Lm + 1.0;
|
||||
|
||||
// determin C_{nx}, C_{ny}, C_{nz}
|
||||
pos_type Cm(dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1),
|
||||
dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1),
|
||||
dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1));
|
||||
|
||||
// determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
pos_type Cp(dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1),
|
||||
dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1),
|
||||
dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1));
|
||||
|
||||
// determine -dC_{nx}/dx, -dC_{ny}/dy, -dC_{nz}/dz
|
||||
pos_type Cvm(drover6[0]*(3*Lm[0]*Lm[0]-1),
|
||||
drover6[1]*(3*Lm[1]*Lm[1]-1),
|
||||
drover6[2]*(3*Lm[2]*Lm[2]-1));
|
||||
// determin -dC_{nx+1}/dx, -dC_{ny+1}/dy, -dC_{nz+1}/dz
|
||||
pos_type Cvp(drover6[0]*(3*Lp[0]*Lp[0]-1),
|
||||
drover6[1]*(3*Lp[1]*Lp[1]-1),
|
||||
drover6[2]*(3*Lp[2]*Lp[2]-1));
|
||||
|
||||
int i,j,k;
|
||||
value_type Lx, Ly, Lz;
|
||||
value_type Cx, Cy, Cz;
|
||||
value_type Cvx, Cvy, Cvz;
|
||||
value_type lap = 0.0;
|
||||
value = 0;
|
||||
|
||||
// precalculate d^2 phi/dx^2, d^2 phi/dy^2 and d^2 phi/dz^2
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
|
||||
// get Lx, Cx, Cvx, and index i to get the value
|
||||
if(xyz[ixyz][0]) { // (1,y,z)
|
||||
Lx = Lp[0]; Cx = Cp[0]; Cvx = Cvp[0]; i = im;
|
||||
}
|
||||
else { // (0,y,z)
|
||||
Lx = Lm[0]; Cx = Cm[0]; Cvx = Cvm[0]; i = ip;
|
||||
}
|
||||
|
||||
// get Ly, Cy, Cvy, and index j to get the value
|
||||
if(xyz[ixyz][1]) { // (x,1,z)
|
||||
Ly = Lp[1]; Cy = Cp[1]; Cvy = Cvp[1]; j = jm;
|
||||
}
|
||||
else { // (x,0,z)
|
||||
Ly = Lm[1]; Cy = Cm[1]; Cvy = Cvm[1]; j = jp;
|
||||
}
|
||||
|
||||
// get Lz, Cz, Cvz, and index k to get the value
|
||||
if(xyz[ixyz][2]) { // (x,y,1)
|
||||
Lz = Lp[2]; Cz = Cp[2]; Cvz = Cvp[2]; k = km;
|
||||
}
|
||||
else { // (x,y,0)
|
||||
Lz = Lm[2]; Cz = Cm[2]; Cvz = Cvm[2]; k = kp;
|
||||
}
|
||||
|
||||
value_type y = Y(i,j,k);
|
||||
|
||||
//\warning: not protected for out-of-bound indices
|
||||
value_type y2x = (Y(i+1,j, k) +Y(i-1,j, k) -2.0*y)*drinv2[0];
|
||||
value_type y2y = (Y(i, j+1,k) +Y(i, j-1,k) -2.0*y)*drinv2[1];
|
||||
value_type y2z = (Y(i, j, k+1)+Y(i, j, k-1)-2.0*y)*drinv2[2];
|
||||
|
||||
if(xyz[ixyz][3]) {//positive
|
||||
value += (Lx*Ly*Lz*y + Cx*Ly*Lz*y2x + Lx*Cy*Lz*y2y + Lx*Ly*Cz*y2z);
|
||||
lap += Lx*Ly*Lz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
// Cvx = -dC/dx, Cvy = -dC/dy, and Cvz = -dC/dz
|
||||
// dL/dx = -1/dx
|
||||
gr[0] -= (drinv[0]*(Ly*Lz*y+Cy*Lz*y2y+Ly*Cz*y2z) + Cvx*Ly *Lz *y2x);
|
||||
gr[1] -= (drinv[1]*(Lz*Lx*y+Cz*Lx*y2z+Lz*Cx*y2x) + Lx *Cvy*Lz *y2y);
|
||||
gr[2] -= (drinv[2]*(Lx*Ly*y+Cx*Ly*y2x+Lx*Cy*y2y) + Lx *Ly *Cvz*y2z);
|
||||
|
||||
} else {
|
||||
value -= (Lx*Ly*Lz*y +Cx*Ly*Lz*y2x + Lx*Cy*Lz*y2y + Lx*Ly*Cz*y2z);
|
||||
lap -= Lx*Ly*Lz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
gr[0] += (drinv[0]*(Ly*Lz*y +Cy*Lz*y2y + Ly*Cz*y2z) + Cvx*Ly *Lz *y2x);
|
||||
gr[1] += (drinv[1]*(Lz*Lx*y +Cz*Lx*y2z + Lz*Cx*y2x) + Lx *Cvy*Lz *y2y);
|
||||
gr[2] += (drinv[2]*(Lx*Ly*y +Cx*Ly*y2x + Lx*Cy*y2y) + Lx *Ly *Cvz*y2z);
|
||||
}
|
||||
}
|
||||
return lap;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,353 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
#define CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
|
||||
#include <bitset>
|
||||
using std::bitset;
|
||||
|
||||
template<class PosA>
|
||||
struct CubicSpline3DGrid {
|
||||
|
||||
typedef PosA pos_type;
|
||||
typedef typename PosA::Type_t value_type;
|
||||
|
||||
int Npt[3];
|
||||
value_type reps;
|
||||
pos_type CurrentPos;
|
||||
pos_type Rmin, Rmax, dr, drinv, drinv2, dr2over6, drover6;
|
||||
bitset<4> xyz[8];
|
||||
pos_type L[8], C[8], dC[8];
|
||||
int I[8][3];
|
||||
|
||||
CubicSpline3DGrid() {
|
||||
setxyz();
|
||||
Rmin[0] = 0.0; Rmin[1] = 0.0; Rmin[2] = 0.0;
|
||||
Rmax[0] = 1.0; Rmax[1] = 1.0; Rmax[2] = 1.0;
|
||||
resize(1,1,1);
|
||||
}
|
||||
|
||||
CubicSpline3DGrid(const CubicSpline3DGrid<PosA>& g) {
|
||||
setxyz();
|
||||
Rmin = g.Rmin;
|
||||
Rmax = g.Rmax;
|
||||
resize(g.Npt[0], g.Npt[1], g.Npt[2]);
|
||||
}
|
||||
|
||||
CubicSpline3DGrid<PosA>& operator=(const CubicSpline3DGrid<PosA>& g) {
|
||||
setxyz();
|
||||
Rmin = g.Rmin;
|
||||
Rmax = g.Rmax;
|
||||
resize(g.Npt[0], g.Npt[1], g.Npt[2]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return 1/dr^2 for the 2nd-derivatives
|
||||
inline value_type c2(int i) const { return drinv2[i];}
|
||||
|
||||
// return 1/dr for the 2nd-derivatives
|
||||
inline value_type c1(int i) const { return drinv[i];}
|
||||
|
||||
void resize(int l, int m, int n) {
|
||||
|
||||
Npt[0] = l; Npt[1] =m; Npt[2] = n;
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
dr[0] = (Rmax[0]-Rmin[0])/static_cast<value_type>(Npt[0]);
|
||||
dr[1] = (Rmax[1]-Rmin[1])/static_cast<value_type>(Npt[1]);
|
||||
dr[2] = (Rmax[2]-Rmin[2])/static_cast<value_type>(Npt[2]);
|
||||
|
||||
// minimim distance 1/100 th of the distance, to be over written
|
||||
reps = 1e-6; //rcut2 = dot(dr,dr)/1000000;
|
||||
CurrentPos = PosA(1000, 1000, 1000);
|
||||
|
||||
drinv[0] = 1.0/dr[0];
|
||||
drinv[1] = 1.0/dr[1];
|
||||
drinv[2] = 1.0/dr[2];
|
||||
drinv2[0] = drinv[0]*drinv[0];
|
||||
drinv2[1] = drinv[1]*drinv[1];
|
||||
drinv2[2] = drinv[2]*drinv[2];
|
||||
drover6[0] = dr[0]/6.0;
|
||||
drover6[1] = dr[1]/6.0;
|
||||
drover6[2] = dr[2]/6.0;
|
||||
dr2over6[0] = dr[0]*drover6[0];
|
||||
dr2over6[1] = dr[1]*drover6[1];
|
||||
dr2over6[2] = dr[2]*drover6[2];
|
||||
}
|
||||
|
||||
|
||||
void setxyz(){
|
||||
//4-bit to calculate the coefficient indices and sign
|
||||
//xyz[i](x,y,z,sign): initially, all the bits are set to 0
|
||||
//xyz[0] = bitset<4>(0,0,0,0); // -1(0) 3*0
|
||||
xyz[1].flip(2); xyz[1].flip(3); //xyz[1] = bitset<4>(0,0,1,1); // +1(1) 2*0
|
||||
xyz[2].flip(1); xyz[2].flip(2); //xyz[2] = bitset<4>(0,1,1,0); // -1(0) 1*0
|
||||
xyz[3].flip(1); xyz[3].flip(3); //xyz[3] = bitset<4>(0,1,0,1); // +1(1) 2*0
|
||||
xyz[4].flip(0); xyz[4].flip(3); //xyz[4] = bitset<4>(1,0,0,1); // +1(1) 2*0
|
||||
xyz[5].flip(0); xyz[5].flip(2); //xyz[5] = bitset<4>(1,0,1,0); // -1(0) 1*0
|
||||
xyz[6].flip(); //xyz[6] = bitset<4>(1,1,1,1); // +1(1) 0*0
|
||||
xyz[7].flip(0); xyz[7].flip(1); //xyz[7] = bitset<4>(1,1,0,0); // -1(0) 1*0
|
||||
}
|
||||
|
||||
inline bool get(const pos_type& pos) {
|
||||
|
||||
//how much the gain will be???
|
||||
//if(dot(CurrentPos,pos) > rcut2) {
|
||||
if(fabs(CurrentPos[0]-pos[0])>reps
|
||||
&& fabs(CurrentPos[1]-pos[1])>reps
|
||||
&& fabs(CurrentPos[2]-pos[2])>reps) {
|
||||
// find the location of pos
|
||||
value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// find the index of pos
|
||||
int im = static_cast<int>(di);
|
||||
int jm = static_cast<int>(dj);
|
||||
int km = static_cast<int>(dk);
|
||||
|
||||
// find the index+1 of pos
|
||||
int ip = im+1;
|
||||
int jp = jm+1;
|
||||
int kp = km+1;
|
||||
|
||||
// determin L_{nx}, L_{ny}, L_{nz}
|
||||
//\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
pos_type Lm(static_cast<value_type>(im)-di,
|
||||
static_cast<value_type>(jm)-dj,
|
||||
static_cast<value_type>(km)-dk);
|
||||
|
||||
// determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
//\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
//= -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
pos_type Lp = Lm + 1.0;
|
||||
|
||||
// determin C_{nx}, C_{ny}, C_{nz}
|
||||
pos_type Cm(dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1),
|
||||
dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1),
|
||||
dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1));
|
||||
|
||||
// determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
pos_type Cp(dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1),
|
||||
dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1),
|
||||
dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1));
|
||||
|
||||
// determine -dC_{nx}/dx, -dC_{ny}/dy, -dC_{nz}/dz
|
||||
pos_type Cvm(drover6[0]*(3*Lm[0]*Lm[0]-1),
|
||||
drover6[1]*(3*Lm[1]*Lm[1]-1),
|
||||
drover6[2]*(3*Lm[2]*Lm[2]-1));
|
||||
// determin -dC_{nx+1}/dx, -dC_{ny+1}/dy, -dC_{nz+1}/dz
|
||||
pos_type Cvp(drover6[0]*(3*Lp[0]*Lp[0]-1),
|
||||
drover6[1]*(3*Lp[1]*Lp[1]-1),
|
||||
drover6[2]*(3*Lp[2]*Lp[2]-1));
|
||||
CurrentPos = pos; // save input position
|
||||
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
//get Lx, Cx, Cvx, and index i to get the value
|
||||
if(xyz[ixyz][0]) { //(1,y,z)
|
||||
L[ixyz][0] = Lp[0];
|
||||
C[ixyz][0] = Cp[0];
|
||||
dC[ixyz][0] = Cvp[0];
|
||||
I[ixyz][0] = im;
|
||||
}
|
||||
else { //(0,y,z)
|
||||
L[ixyz][0] = Lm[0];
|
||||
C[ixyz][0] = Cm[0];
|
||||
dC[ixyz][0] = Cvm[0];
|
||||
I[ixyz][0] = ip;
|
||||
}
|
||||
|
||||
//get Ly, Cy, Cvy, and index j to get the value
|
||||
if(xyz[ixyz][1]) { //(x,1,z)
|
||||
L[ixyz][1] = Lp[1];
|
||||
C[ixyz][1] = Cp[1];
|
||||
dC[ixyz][1] = Cvp[1];
|
||||
I[ixyz][1] = jm;
|
||||
}
|
||||
else { //(x,0,z)
|
||||
L[ixyz][1] = Lm[1];
|
||||
C[ixyz][1] = Cm[1];
|
||||
dC[ixyz][1] = Cvm[1];
|
||||
I[ixyz][1] = jp;
|
||||
}
|
||||
|
||||
//get Lz, Cz, Cvz, and index k to get the value
|
||||
if(xyz[ixyz][2]) { //(x,y,1)
|
||||
L[ixyz][2] = Lp[2];
|
||||
C[ixyz][2] = Cp[2];
|
||||
dC[ixyz][2] = Cvp[2];
|
||||
I[ixyz][2] = km;
|
||||
}
|
||||
else { //(x,y,0)
|
||||
L[ixyz][2] = Lm[2];
|
||||
C[ixyz][2] = Cm[2];
|
||||
dC[ixyz][2] = Cvm[2];
|
||||
I[ixyz][2] = kp;
|
||||
}
|
||||
}
|
||||
return true; // new values are evaluated
|
||||
}
|
||||
else
|
||||
return false; // position is identical
|
||||
}
|
||||
};
|
||||
|
||||
/*! \class template<class T> CubicSpline3D
|
||||
* \brief spline functions on 3D regular grid [Rmin, Rmax)^3
|
||||
* The number of grids per axis can vary.
|
||||
* A set of orbitals are associated with a CubicSpline3D.
|
||||
* This class cannot destroy the orbitals. They have to be provided externally.
|
||||
*/
|
||||
|
||||
template<class grid_type,class orb_type>
|
||||
struct CubicSpline3D {
|
||||
|
||||
typedef typename grid_type::pos_type pos_type;
|
||||
typedef typename orb_type::value_type value_type;
|
||||
|
||||
bool OwnGrid;
|
||||
value_type Val, Lap;
|
||||
pos_type Grad;
|
||||
|
||||
grid_type* myGrid; // grid
|
||||
orb_type Orb;
|
||||
|
||||
//!< default constructor
|
||||
CubicSpline3D(): OwnGrid(false) {}
|
||||
|
||||
//!< constructor using grid
|
||||
CubicSpline3D(int l, int m, int n): OwnGrid(true){
|
||||
myGrid = new grid_type;
|
||||
myGrid->resize(l,m,n);
|
||||
resize(l, m, n);
|
||||
}
|
||||
|
||||
//!< copy constructor
|
||||
CubicSpline3D(const CubicSpline3D<grid_type,orb_type>& a){
|
||||
OwnGrid = false;
|
||||
myGrid = a.myGrid;
|
||||
resize(myGrid->Npt[0], myGrid->Npt[1], myGrid->Npt[2]);
|
||||
}
|
||||
|
||||
void resize(int l, int m, int n) {
|
||||
Orb.resize(l+1,m+1,n+1);
|
||||
}
|
||||
|
||||
~CubicSpline3D(){
|
||||
if(OwnGrid) {
|
||||
cerr << "This CubicSpline3D owns grid. Delete it" << endl;
|
||||
delete myGrid;
|
||||
}
|
||||
}
|
||||
// assign value at (i,j,k) of iorb-th orbital
|
||||
value_type& operator()(int i, int j, int k) {
|
||||
return Orb(i,j,k);
|
||||
}
|
||||
|
||||
// return value at (i,j,k) of iorb-th orbital
|
||||
value_type operator()(int i, int j, int k) const {
|
||||
return Orb(i,j,k);
|
||||
}
|
||||
|
||||
// always return the current value
|
||||
value_type laplacian(const pos_type& pos) {
|
||||
myGrid->get(pos);
|
||||
do_evaluate(pos);
|
||||
return Val;
|
||||
}
|
||||
|
||||
// always return the current value
|
||||
value_type evaluate(const pos_type& pos) {
|
||||
myGrid->get(pos);
|
||||
do_evaluate(pos);
|
||||
return Val;
|
||||
}
|
||||
|
||||
//!< function to calculate value, gradient and laplacian
|
||||
//update Val, Grad and Lap
|
||||
void do_evaluate(const pos_type& pos) {
|
||||
|
||||
// using myGrid data members pre-calculated by myGrid.get(pos)
|
||||
// \li Linear coefficients: Lm, Lp
|
||||
// \li Cubic coefficients: Cm, Cp
|
||||
// \li Gradient of Cubic coefficients: Cvm, Cvp
|
||||
// \li I : index of the (nx,ny,nz)
|
||||
// \li Ip : index of the (nx+1,ny+1,nz+1)
|
||||
Val = 0.0;
|
||||
Lap = 0.0;
|
||||
Grad = 0.0;
|
||||
value_type val, lap;
|
||||
pos_type gr;
|
||||
// precalculate d^2 phi/dx^2, d^2 phi/dy^2 and d^2 phi/dz^2
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
|
||||
int i = myGrid->I[ixyz][0];
|
||||
int j = myGrid->I[ixyz][1];
|
||||
int k = myGrid->I[ixyz][2];
|
||||
value_type y = Orb(i,j,k);
|
||||
|
||||
//\warning: not protected for negative indices
|
||||
value_type y2x=(Orb(i+1,j,k)+Orb(i-1,j,k)-2.0*y)*myGrid->c2(0);
|
||||
value_type y2y=(Orb(i,j+1,k)+Orb(i,j-1,k)-2.0*y)*myGrid->c2(1);
|
||||
value_type y2z=(Orb(i,j,k+1)+Orb(i,j,k-1)-2.0*y)*myGrid->c2(2);
|
||||
|
||||
value_type lxy = myGrid->L[ixyz][0]*myGrid->L[ixyz][1];
|
||||
value_type lyz = myGrid->L[ixyz][1]*myGrid->L[ixyz][2];
|
||||
value_type lzx = myGrid->L[ixyz][2]*myGrid->L[ixyz][0];
|
||||
value_type lxyz = lxy*myGrid->L[ixyz][2];
|
||||
value_type cxx = myGrid->C[ixyz][0]*y2x;
|
||||
value_type cyy = myGrid->C[ixyz][1]*y2y;
|
||||
value_type czz = myGrid->C[ixyz][2]*y2z;
|
||||
|
||||
val = lxyz*y + cxx*lyz + cyy*lzx + czz*lxy;
|
||||
lap = lxyz*(y2x+y2y+y2z);
|
||||
|
||||
gr[0] = lyz*(myGrid->c1(0)*y+myGrid->dC[ixyz][0]*y2x)
|
||||
+ myGrid->c1(0)*(cyy*myGrid->L[ixyz][2]+czz*myGrid->L[ixyz][1]);
|
||||
|
||||
gr[1] = lzx*(myGrid->c1(1)*y+myGrid->dC[ixyz][1]*y2y)
|
||||
+ myGrid->c1(1)*(czz*myGrid->L[ixyz][0]+cxx*myGrid->L[ixyz][2]);
|
||||
|
||||
gr[2] = lxy*(myGrid->c1(2)*y+myGrid->dC[ixyz][2]*y2z)
|
||||
+ myGrid->c1(2)*(cxx*myGrid->L[ixyz][1]+cyy*myGrid->L[ixyz][0]);
|
||||
|
||||
if(myGrid->xyz[ixyz][3]) {//positive
|
||||
Val += val;
|
||||
Lap += lap;
|
||||
Grad -= gr;
|
||||
} else {
|
||||
Val -= val;
|
||||
Lap -= lap;
|
||||
Grad += gr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,351 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
#define CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
|
||||
template<class PosA>
|
||||
struct CubicSpline3DGrid {
|
||||
|
||||
typedef PosA pos_type;
|
||||
typedef typename PosA::Type_t value_type;
|
||||
|
||||
int Npt[3];
|
||||
value_type rcut2;
|
||||
pos_type CurrentPos;
|
||||
pos_type Rmin, Rmax, dr, drinv, drinv2, dr2over6, drover6;
|
||||
pos_type Lm, Lp, Cm, Cp, Cvm, Cvp;
|
||||
int I[3], Ip[3];
|
||||
|
||||
CubicSpline3DGrid() {
|
||||
Rmin[0] = 0.0; Rmin[1] = 0.0; Rmin[2] = 0.0;
|
||||
Rmax[0] = 1.0; Rmax[1] = 1.0; Rmax[2] = 1.0;
|
||||
resize(1,1,1);
|
||||
}
|
||||
|
||||
CubicSpline3DGrid(const CubicSpline3DGrid<PosA>& g) {
|
||||
Rmin = g.Rmin;
|
||||
Rmax = g.Rmax;
|
||||
resize(g.Npt[0], g.Npt[1], g.Npt[2]);
|
||||
}
|
||||
|
||||
CubicSpline3DGrid<PosA>& operator=(const CubicSpline3DGrid<PosA>& g) {
|
||||
Rmin = g.Rmin;
|
||||
Rmax = g.Rmax;
|
||||
resize(g.Npt[0], g.Npt[1], g.Npt[2]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return 1/dr^2 for the 2nd-derivatives
|
||||
inline value_type c2(int i) const { return drinv2[i];}
|
||||
|
||||
// return 1/dr for the 2nd-derivatives
|
||||
inline value_type c1(int i) const { return drinv[i];}
|
||||
|
||||
void resize(int l, int m, int n) {
|
||||
Npt[0] = l; Npt[1] =m; Npt[2] = n;
|
||||
dr[0] = (Rmax[0]-Rmin[0])/static_cast<value_type>(l);
|
||||
dr[1] = (Rmax[1]-Rmin[1])/static_cast<value_type>(m);
|
||||
dr[2] = (Rmax[2]-Rmin[2])/static_cast<value_type>(n);
|
||||
|
||||
// minimim distance 1/100 th of the distance, to be over written
|
||||
rcut2 = dot(dr,dr)/1000000;
|
||||
CurrentPos = PosA(1000, 1000, 1000);
|
||||
|
||||
drinv[0] = 1.0/dr[0];
|
||||
drinv[1] = 1.0/dr[1];
|
||||
drinv[2] = 1.0/dr[2];
|
||||
drinv2[0] = drinv[0]*drinv[0];
|
||||
drinv2[1] = drinv[1]*drinv[1];
|
||||
drinv2[2] = drinv[2]*drinv[2];
|
||||
drover6[0] = dr[0]/6.0;
|
||||
drover6[1] = dr[1]/6.0;
|
||||
drover6[2] = dr[2]/6.0;
|
||||
dr2over6[0] = dr[0]*drover6[0];
|
||||
dr2over6[1] = dr[1]*drover6[1];
|
||||
dr2over6[2] = dr[2]*drover6[2];
|
||||
}
|
||||
|
||||
|
||||
inline bool get(const pos_type& pos) {
|
||||
|
||||
//how much the gain will be???
|
||||
//if(dot(CurrentPos,pos) > rcut2) {
|
||||
if(fabs(CurrentPos[0]-pos[0])>1e-6
|
||||
&& fabs(CurrentPos[1]-pos[1])>1e-6 && fabs(CurrentPos[2]-pos[2])>1e-6) {
|
||||
// find the location of pos
|
||||
value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// find the index of pos
|
||||
I[0] = static_cast<int>(di);
|
||||
I[1] = static_cast<int>(dj);
|
||||
I[2] = static_cast<int>(dk);
|
||||
|
||||
// find the index+1 of pos
|
||||
Ip[0] = I[0]+1;
|
||||
Ip[1] = I[1]+1;
|
||||
Ip[2] = I[2]+1;
|
||||
|
||||
// determin L_{nx}, L_{ny}, L_{nz}
|
||||
//\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
Lm[0] = static_cast<value_type>(I[0])-di;
|
||||
Lm[1] = static_cast<value_type>(I[1])-dj;
|
||||
Lm[2] = static_cast<value_type>(I[2])-dk;
|
||||
|
||||
// determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
//\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
//= -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
Lp = Lm + 1.0;
|
||||
|
||||
// determin C_{nx}, C_{ny}, C_{nz}
|
||||
Cm[0] = dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1);
|
||||
Cm[1] = dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1);
|
||||
Cm[2] = dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1);
|
||||
|
||||
// determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
Cp[0] = dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1);
|
||||
Cp[1] = dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1);
|
||||
Cp[2] = dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1);
|
||||
|
||||
// determine -dC_{nx}/dx, -dC_{ny}/dy, -dC_{nz}/dz
|
||||
Cvm[0] = drover6[0]*(3*Lm[0]*Lm[0]-1);
|
||||
Cvm[1] = drover6[1]*(3*Lm[1]*Lm[1]-1);
|
||||
Cvm[2] = drover6[2]*(3*Lm[2]*Lm[2]-1);
|
||||
// determin -dC_{nx+1}/dx, -dC_{ny+1}/dy, -dC_{nz+1}/dz
|
||||
Cvp[0] = drover6[0]*(3*Lp[0]*Lp[0]-1);
|
||||
Cvp[1] = drover6[1]*(3*Lp[1]*Lp[1]-1);
|
||||
Cvp[2] = drover6[2]*(3*Lp[2]*Lp[2]-1);
|
||||
CurrentPos = pos; // save input position
|
||||
return true; // new values are evaluated
|
||||
}
|
||||
else
|
||||
return false; // position is identical
|
||||
}
|
||||
};
|
||||
|
||||
#include <bitset>
|
||||
using std::bitset;
|
||||
/*! \class template<class T> CubicSpline3D
|
||||
* \brief spline functions on 3D regular grid [Rmin, Rmax)^3
|
||||
* The number of grids per axis can vary.
|
||||
* A set of orbitals are associated with a CubicSpline3D.
|
||||
* This class cannot destroy the orbitals. They have to be provided externally.
|
||||
*/
|
||||
|
||||
template<class grid_type,class orb_type>
|
||||
struct CubicSpline3D {
|
||||
|
||||
typedef typename orb_type::value_type value_type;
|
||||
typedef typename grid_type::pos_type pos_type;
|
||||
|
||||
int OrbitalID;
|
||||
bitset<4> xyz[8]; // \note possible to make it "static const"
|
||||
grid_type myGrid; // grid
|
||||
vector<orb_type*> Orb; // a set of orbitals
|
||||
Vector<value_type> Val,Lap;
|
||||
Vector<pos_type> Grad;
|
||||
|
||||
//!< default constructor
|
||||
CubicSpline3D(): OrbitalID(-1) {
|
||||
setxyz(); // set bit operators
|
||||
myGrid.resize(1,1,1); // set the default variables
|
||||
}
|
||||
|
||||
//!< constructor using grid
|
||||
CubicSpline3D(int l, int m, int n): OrbitalID(-1){
|
||||
setxyz(); // set bit operators
|
||||
myGrid.resize(l,m,n);
|
||||
}
|
||||
|
||||
//!< copy constructor
|
||||
CubicSpline3D(const CubicSpline3D<grid_type,orb_type>& a): OrbitalID(-1){
|
||||
setxyz(); // set bit operators
|
||||
myGrid = a.myGrid;
|
||||
Val = a.Val;
|
||||
Lap = a.Lap;
|
||||
Grad = a.Grad;
|
||||
Orb.reserve(a.Orb.size());
|
||||
for(int iorb=0; iorb< a.Orb.size(); iorb++) Orb.push_back(a.Orb[iorb]);
|
||||
}
|
||||
|
||||
~CubicSpline3D(){ }
|
||||
|
||||
void setxyz(){
|
||||
//4-bit to calculate the coefficient indices and sign
|
||||
//xyz[i](x,y,z,sign): initially, all the bits are set to 0
|
||||
//xyz[0] = bitset<4>(0,0,0,0); // -1(0) 3*0
|
||||
xyz[1].flip(2); xyz[1].flip(3); //xyz[1] = bitset<4>(0,0,1,1); // +1(1) 2*0
|
||||
xyz[2].flip(1); xyz[2].flip(2); //xyz[2] = bitset<4>(0,1,1,0); // -1(0) 1*0
|
||||
xyz[3].flip(1); xyz[3].flip(3); //xyz[3] = bitset<4>(0,1,0,1); // +1(1) 2*0
|
||||
xyz[4].flip(0); xyz[4].flip(3); //xyz[4] = bitset<4>(1,0,0,1); // +1(1) 2*0
|
||||
xyz[5].flip(0); xyz[5].flip(2); //xyz[5] = bitset<4>(1,0,1,0); // -1(0) 1*0
|
||||
xyz[6].flip(); //xyz[6] = bitset<4>(1,1,1,1); // +1(1) 0*0
|
||||
xyz[7].flip(0); xyz[7].flip(1); //xyz[7] = bitset<4>(1,1,0,0); // -1(0) 1*0
|
||||
}
|
||||
|
||||
// assign value at (i,j,k) of iorb-th orbital
|
||||
value_type& operator()(int iorb, int i, int j, int k) {
|
||||
return Orb[iorb]->operator()(i,j,k);
|
||||
}
|
||||
|
||||
// return value at (i,j,k) of iorb-th orbital
|
||||
value_type operator()(int iorb, int i, int j, int k) const {
|
||||
return Orb[iorb]->operator()(i,j,k);
|
||||
}
|
||||
|
||||
|
||||
//!\fn int add(grid_type* orbital)
|
||||
//!\param orbital a grid_type to be added to Orb
|
||||
//!\return the index of the added orbital
|
||||
//!\warning Assuming that the new orbital is the same kind, i.e., size and grid
|
||||
int add(orb_type* orbital) {
|
||||
int id = Orb.size();
|
||||
Orb.push_back(orbital);
|
||||
|
||||
// simply resize it
|
||||
Val.resize(id+1);
|
||||
Lap.resize(id+1);
|
||||
Grad.resize(id+1);
|
||||
return id;
|
||||
}
|
||||
|
||||
//!< function to calculate value, gradient and laplacian
|
||||
//\return value[iorb] = value of iorb-th orbial
|
||||
// gr[iorb] = gradient of iorb-th orbial
|
||||
// lap[iorb] = laplacian of iorb-th orbial
|
||||
inline void laplacian(const pos_type& pos) {
|
||||
|
||||
//grid returns true, if pos != myGrid.CurrentPos;
|
||||
if(myGrid.get(pos)) {
|
||||
get_laplacian(pos, Val, Grad, Lap);// evalulate everything
|
||||
for(int iorb=0; iorb<Orb.size(); iorb++) {//assign the values, not sure if needed
|
||||
Orb[iorb]->Val = Val[iorb];
|
||||
Orb[iorb]->Lap = Lap[iorb];
|
||||
Orb[iorb]->Grad =Grad[iorb];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class ValArray, class PosArray>
|
||||
inline void laplacian(const pos_type& pos, ValArray& value, PosArray& gr, ValArray& lap) {
|
||||
|
||||
if(myGrid.get(pos)) {
|
||||
get_laplacian(pos, value,gr,lap);
|
||||
Val = value; Grad = gr; Lap = lap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//!< function to calculate value, gradient and laplacian
|
||||
//\return value[iorb] = value of iorb-th orbial
|
||||
// gr[iorb] = gradient of iorb-th orbial
|
||||
// lap[iorb] = laplacian of iorb-th orbial
|
||||
template<class ValArray, class PosArray>
|
||||
inline void get_laplacian(const pos_type& pos, ValArray& value, PosArray& gr, ValArray& lap) {
|
||||
// using myGrid data members pre-calculated by myGrid.get(pos)
|
||||
// \li Linear coefficients: Lm, Lp
|
||||
// \li Cubic coefficients: Cm, Cp
|
||||
// \li Gradient of Cubic coefficients: Cvm, Cvp
|
||||
// \li I : index of the (nx,ny,nz)
|
||||
// \li Ip : index of the (nx+1,ny+1,nz+1)
|
||||
|
||||
value =0.0; lap = 0.0; gr = 0.0;
|
||||
int i,j,k;
|
||||
value_type Lx, Ly, Lz;
|
||||
value_type Cx, Cy, Cz;
|
||||
value_type Cvx, Cvy, Cvz;
|
||||
|
||||
// precalculate d^2 phi/dx^2, d^2 phi/dy^2 and d^2 phi/dz^2
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
|
||||
// get Lx, Cx, Cvx, and index i to get the value
|
||||
if(xyz[ixyz][0]) { // (1,y,z)
|
||||
Lx = myGrid.Lp[0]; Cx = myGrid.Cp[0]; Cvx = myGrid.Cvp[0]; i = myGrid.I[0];
|
||||
}
|
||||
else { // (0,y,z)
|
||||
Lx = myGrid.Lm[0]; Cx = myGrid.Cm[0]; Cvx = myGrid.Cvm[0]; i = myGrid.Ip[0];
|
||||
}
|
||||
|
||||
// get Ly, Cy, Cvy, and index j to get the value
|
||||
if(xyz[ixyz][1]) { // (x,1,z)
|
||||
Ly = myGrid.Lp[1]; Cy = myGrid.Cp[1]; Cvy = myGrid.Cvp[1]; j = myGrid.I[1];
|
||||
}
|
||||
else { // (x,0,z)
|
||||
Ly = myGrid.Lm[1]; Cy = myGrid.Cm[1]; Cvy = myGrid.Cvm[1]; j = myGrid.Ip[1];
|
||||
}
|
||||
|
||||
// get Lz, Cz, Cvz, and index k to get the value
|
||||
if(xyz[ixyz][2]) { // (x,y,1)
|
||||
Lz = myGrid.Lp[2]; Cz = myGrid.Cp[2]; Cvz = myGrid.Cvp[2]; k = myGrid.I[2];
|
||||
}
|
||||
else { // (x,y,0)
|
||||
Lz = myGrid.Lm[2]; Cz = myGrid.Cm[2]; Cvz = myGrid.Cvm[2]; k = myGrid.Ip[2];
|
||||
}
|
||||
|
||||
value_type lxy = Lx*Ly;
|
||||
value_type lyz = Ly*Lz;
|
||||
value_type lzx = Lz*Lx;
|
||||
value_type lxyz = lxy*Lz;
|
||||
|
||||
for(int iorb=0; iorb<Orb.size(); iorb++) {
|
||||
|
||||
value_type y = (*Orb[iorb])(i,j,k);
|
||||
|
||||
//\warning: not protected for negative indices
|
||||
value_type y2x=((*Orb[iorb])(i+1,j,k)+(*Orb[iorb])(i-1,j,k)-2.0*y)*myGrid.c2(0);
|
||||
value_type y2y=((*Orb[iorb])(i,j+1,k)+(*Orb[iorb])(i,j-1,k)-2.0*y)*myGrid.c2(1);
|
||||
value_type y2z=((*Orb[iorb])(i,j,k+1)+(*Orb[iorb])(i,j,k-1)-2.0*y)*myGrid.c2(2);
|
||||
|
||||
if(xyz[ixyz][3]) {//positive
|
||||
value[iorb] += (lxyz*y + Cx*lyz*y2x + Cy*lzx*y2y + Cz*lxy*y2z);
|
||||
lap[iorb] += lxyz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
// Cvx = -dC/dx, Cvy = -dC/dy, and Cvz = -dC/dz
|
||||
// dL/dx = -1/dx
|
||||
gr[iorb][0] -= (myGrid.c1(0)*(lyz*y+Cy*Lz*y2y+Ly*Cz*y2z) + Cvx*lyz*y2x);
|
||||
gr[iorb][1] -= (myGrid.c1(1)*(lzx*y+Cz*Lx*y2z+Lz*Cx*y2x) + Cvy*lzx*y2y);
|
||||
gr[iorb][2] -= (myGrid.c1(2)*(lxy*y+Cx*Ly*y2x+Lx*Cy*y2y) + Cvz*lxy*y2z);
|
||||
|
||||
} else {
|
||||
value[iorb] -= (lxyz*y + Cx*lyz*y2x + Cy*lzx*y2y + Cz*lxy*y2z);
|
||||
lap[iorb] -= lxyz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
// Cvx = -dC/dx, Cvy = -dC/dy, and Cvz = -dC/dz
|
||||
// dL/dx = -1/dx
|
||||
gr[iorb][0] += (myGrid.c1(0)*(lyz*y+Cy*Lz*y2y+Ly*Cz*y2z) + Cvx*lyz*y2x);
|
||||
gr[iorb][1] += (myGrid.c1(1)*(lzx*y+Cz*Lx*y2z+Lz*Cx*y2x) + Cvy*lzx*y2y);
|
||||
gr[iorb][2] += (myGrid.c1(2)*(lxy*y+Cx*Ly*y2x+Lx*Cy*y2y) + Cvz*lxy*y2z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,325 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
#define CUBICSPLINE3DCOLLECTION_REGULARGRID_H
|
||||
|
||||
#include <bitset>
|
||||
using std::bitset;
|
||||
|
||||
/*! \class template<class T> CubicSpline3D
|
||||
* \brief spline functions on 3D regular grid [Rmin, Rmax)^3
|
||||
* The number of grids per axis can vary.
|
||||
* A set of orbitals are associated with a CubicSpline3D.
|
||||
* This class cannot destroy the orbitals. They have to be provided externally.
|
||||
*/
|
||||
|
||||
template<class grid_type, class pos_type>
|
||||
struct CubicSpline3D {
|
||||
|
||||
typedef typename grid_type::value_type value_type;
|
||||
|
||||
int Npt[3];
|
||||
int OrbitalID;
|
||||
pos_type Rmin, Rmax, dr, drinv, drinv2, dr2over6, drover6;
|
||||
bitset<4> xyz[8]; // \note possible to make it "static const"
|
||||
pos_type Lm, Lp, Cm, Cp, Cvm, Cvp;
|
||||
int I[3], J[3];
|
||||
|
||||
vector<grid_type*> Orb; // a set of orbitals
|
||||
//!< default constructor
|
||||
CubicSpline3D(): OrbitalID(-1) {
|
||||
setxyz(); // set bit operators
|
||||
|
||||
// default bounds [0,1)x[0,1)x[0,1) with 1x1x1 grid
|
||||
Npt[0] = 1; Npt[1] = 1; Npt[2] = 1;
|
||||
Rmin[0] = 0.0; Rmin[1] = 0.0; Rmin[2] = 0.0;
|
||||
Rmax[0] = 1.0; Rmax[1] = 1.0; Rmax[2] = 1.0;
|
||||
resize(1,1,1); // set the default variables
|
||||
}
|
||||
|
||||
//!< constructor using grid
|
||||
CubicSpline3D(int l, int m, int n): OrbitalID(-1){
|
||||
|
||||
setxyz(); // set bit operators
|
||||
Rmin[0] = 0.0; Rmin[1] = 0.0; Rmin[2] = 0.0;
|
||||
Rmax[0] = 1.0; Rmax[1] = 1.0; Rmax[2] = 1.0;
|
||||
|
||||
resize(l,m,n);
|
||||
}
|
||||
|
||||
//!< copy constructor
|
||||
CubicSpline3D(const CubicSpline3D<grid_type,pos_type>& a): OrbitalID(-1){
|
||||
setxyz(); // set bit operators
|
||||
|
||||
Rmin = a.Rmin;
|
||||
Rmax = a.Rmax;
|
||||
resize(a.Npt[0], a.Npt[1], a.Npt[2]);
|
||||
|
||||
Orb.reserve(a.Orb.size());
|
||||
for(int iorb=0; iorb< a.Orb.size(); iorb++) Orb.push_back(a.Orb[iorb]);
|
||||
}
|
||||
|
||||
~CubicSpline3D(){ }
|
||||
|
||||
void setxyz();
|
||||
|
||||
// assign value at (i,j,k) of iorb-th orbital
|
||||
value_type& operator()(int iorb, int i, int j, int k) {
|
||||
return Orb[iorb]->operator()(i,j,k);
|
||||
}
|
||||
|
||||
// return value at (i,j,k) of iorb-th orbital
|
||||
value_type operator()(int iorb, int i, int j, int k) const {
|
||||
return Orb[iorb]->operator()(i,j,k);
|
||||
}
|
||||
|
||||
|
||||
//!\fn int add(grid_type* orbital)
|
||||
//!\param orbital a grid_type to be added to Orb
|
||||
//!\return the index of the added orbital
|
||||
//!\warning Assuming that the new orbital is the same kind, i.e., size and grid
|
||||
int add(grid_type* orbital) {
|
||||
int id = Orb.size();
|
||||
Orb.push_back(orbital);
|
||||
return id;
|
||||
}
|
||||
|
||||
//!< resize the arrays
|
||||
void resize(const int l, const int m, const int n);
|
||||
|
||||
//!< function to calculate value, gradient and laplacian
|
||||
//\return value[iorb] = value of iorb-th orbial
|
||||
// gr[iorb] = gradient of iorb-th orbial
|
||||
// lap[iorb] = laplacian of iorb-th orbial
|
||||
template<class ValArray, class PosArray>
|
||||
void laplacian(const pos_type& pos, ValArray& value, PosArray& gr, ValArray& lap);
|
||||
|
||||
inline void get_grid(const pos_type& pos) {
|
||||
|
||||
// find the location of pos
|
||||
value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// find the index of pos
|
||||
I[0] = static_cast<int>(di);
|
||||
I[1] = static_cast<int>(dj);
|
||||
I[2] = static_cast<int>(dk);
|
||||
|
||||
// find the index+1 of pos
|
||||
J[0] = I[0]+1;
|
||||
J[1] = I[1]+1;
|
||||
J[2] = I[2]+1;
|
||||
|
||||
// determin L_{nx}, L_{ny}, L_{nz}
|
||||
//\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
Lm[0] = static_cast<value_type>(I[0])-di;
|
||||
Lm[1] = static_cast<value_type>(I[1])-dj;
|
||||
Lm[2] = static_cast<value_type>(I[2])-dk;
|
||||
|
||||
// determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
//\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
//= -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
Lp = Lm + 1.0;
|
||||
|
||||
// determin C_{nx}, C_{ny}, C_{nz}
|
||||
Cm[0] = dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1);
|
||||
Cm[1] = dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1);
|
||||
Cm[2] = dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1);
|
||||
|
||||
// determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
Cp[0] = dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1);
|
||||
Cp[1] = dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1);
|
||||
Cp[2] = dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1);
|
||||
|
||||
// determine -dC_{nx}/dx, -dC_{ny}/dy, -dC_{nz}/dz
|
||||
Cvm[0] = drover6[0]*(3*Lm[0]*Lm[0]-1);
|
||||
Cvm[1] = drover6[1]*(3*Lm[1]*Lm[1]-1);
|
||||
Cvm[2] = drover6[2]*(3*Lm[2]*Lm[2]-1);
|
||||
// determin -dC_{nx+1}/dx, -dC_{ny+1}/dy, -dC_{nz+1}/dz
|
||||
Cvp[0] = drover6[0]*(3*Lp[0]*Lp[0]-1);
|
||||
Cvp[1] = drover6[1]*(3*Lp[1]*Lp[1]-1);
|
||||
Cvp[2] = drover6[2]*(3*Lp[2]*Lp[2]-1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class grid_type, class pos_type>
|
||||
void
|
||||
CubicSpline3D<grid_type,pos_type>::resize(const int l, const int m, const int n) {
|
||||
Npt[0] = l; Npt[1] = m; Npt[2] = n;
|
||||
dr[0] = (Rmax[0]-Rmin[0])/static_cast<value_type>(l);
|
||||
dr[1] = (Rmax[1]-Rmin[1])/static_cast<value_type>(m);
|
||||
dr[2] = (Rmax[2]-Rmin[2])/static_cast<value_type>(n);
|
||||
drinv[0] = 1.0/dr[0];
|
||||
drinv[1] = 1.0/dr[1];
|
||||
drinv[2] = 1.0/dr[2];
|
||||
drinv2[0] = drinv[0]*drinv[0];
|
||||
drinv2[1] = drinv[1]*drinv[1];
|
||||
drinv2[2] = drinv[2]*drinv[2];
|
||||
drover6[0] = dr[0]/6.0;
|
||||
drover6[1] = dr[1]/6.0;
|
||||
drover6[2] = dr[2]/6.0;
|
||||
dr2over6[0] = dr[0]*drover6[0];
|
||||
dr2over6[1] = dr[1]*drover6[1];
|
||||
dr2over6[2] = dr[2]*drover6[2];
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class grid_type, class pos_type>
|
||||
template<class ValArray, class PosArray>
|
||||
void
|
||||
CubicSpline3D<grid_type,pos_type>::laplacian(const pos_type& pos,
|
||||
ValArray& value, PosArray& gr,
|
||||
ValArray& lap) {
|
||||
get_grid(pos);
|
||||
|
||||
// // find the location of pos
|
||||
// value_type di = (pos[0]-Rmin[0])*drinv[0];
|
||||
// value_type dj = (pos[1]-Rmin[1])*drinv[1];
|
||||
// value_type dk = (pos[2]-Rmin[2])*drinv[2];
|
||||
|
||||
// // find the index of pos
|
||||
// int im = static_cast<int>(di);
|
||||
// int jm = static_cast<int>(dj);
|
||||
// int km = static_cast<int>(dk);
|
||||
|
||||
// // find the index+1 of pos
|
||||
// int ip = im+1;
|
||||
// int jp = jm+1;
|
||||
// int kp = km+1;
|
||||
|
||||
// // determin L_{nx}, L_{ny}, L_{nz}
|
||||
// //\latex{$$L_{nx} = {R_{min}+nx*dx - x\over dx} = -{x-R_{min}\over dx}+nx$$}
|
||||
// pos_type Lm(static_cast<value_type>(im)-di,
|
||||
// static_cast<value_type>(jm)-dj,
|
||||
// static_cast<value_type>(km)-dk);
|
||||
|
||||
// // determin L_{nx+1}, L_{ny+1}, L_{nz+1}
|
||||
// //\latex{$$L_{nx+1} = {R_{min}+(nx+1)*dx - x\over dx}
|
||||
// //= -{x-R_{min}\over dx}+nx+1 = L_{nx}+1$$}
|
||||
// pos_type Lp = Lm + 1.0;
|
||||
|
||||
// // determin C_{nx}, C_{ny}, C_{nz}
|
||||
// pos_type Cm(dr2over6[0]*Lm[0]*(Lm[0]*Lm[0]-1),
|
||||
// dr2over6[1]*Lm[1]*(Lm[1]*Lm[1]-1),
|
||||
// dr2over6[2]*Lm[2]*(Lm[2]*Lm[2]-1));
|
||||
|
||||
// // determin C_{nx+1}, C_{ny+1}, C_{nz+1}
|
||||
// pos_type Cp(dr2over6[0]*Lp[0]*(Lp[0]*Lp[0]-1),
|
||||
// dr2over6[1]*Lp[1]*(Lp[1]*Lp[1]-1),
|
||||
// dr2over6[2]*Lp[2]*(Lp[2]*Lp[2]-1));
|
||||
|
||||
// // determine -dC_{nx}/dx, -dC_{ny}/dy, -dC_{nz}/dz
|
||||
// pos_type Cvm(drover6[0]*(3*Lm[0]*Lm[0]-1),
|
||||
// drover6[1]*(3*Lm[1]*Lm[1]-1),
|
||||
// drover6[2]*(3*Lm[2]*Lm[2]-1));
|
||||
// // determin -dC_{nx+1}/dx, -dC_{ny+1}/dy, -dC_{nz+1}/dz
|
||||
// pos_type Cvp(drover6[0]*(3*Lp[0]*Lp[0]-1),
|
||||
// drover6[1]*(3*Lp[1]*Lp[1]-1),
|
||||
// drover6[2]*(3*Lp[2]*Lp[2]-1));
|
||||
|
||||
int i,j,k;
|
||||
value_type Lx, Ly, Lz;
|
||||
value_type Cx, Cy, Cz;
|
||||
value_type Cvx, Cvy, Cvz;
|
||||
|
||||
// precalculate d^2 phi/dx^2, d^2 phi/dy^2 and d^2 phi/dz^2
|
||||
for(int ixyz=0; ixyz<8; ixyz++) {
|
||||
|
||||
// get Lx, Cx, Cvx, and index i to get the value
|
||||
if(xyz[ixyz][0]) { // (1,y,z)
|
||||
Lx = Lp[0]; Cx = Cp[0]; Cvx = Cvp[0]; i = I[0];
|
||||
}
|
||||
else { // (0,y,z)
|
||||
Lx = Lm[0]; Cx = Cm[0]; Cvx = Cvm[0]; i = J[0];
|
||||
}
|
||||
|
||||
// get Ly, Cy, Cvy, and index j to get the value
|
||||
if(xyz[ixyz][1]) { // (x,1,z)
|
||||
Ly = Lp[1]; Cy = Cp[1]; Cvy = Cvp[1]; j = I[1];
|
||||
}
|
||||
else { // (x,0,z)
|
||||
Ly = Lm[1]; Cy = Cm[1]; Cvy = Cvm[1]; j = J[1];
|
||||
}
|
||||
|
||||
// get Lz, Cz, Cvz, and index k to get the value
|
||||
if(xyz[ixyz][2]) { // (x,y,1)
|
||||
Lz = Lp[2]; Cz = Cp[2]; Cvz = Cvp[2]; k = I[2];
|
||||
}
|
||||
else { // (x,y,0)
|
||||
Lz = Lm[2]; Cz = Cm[2]; Cvz = Cvm[2]; k = J[2];
|
||||
}
|
||||
|
||||
for(int iorb=0; iorb<Orb.size(); iorb++) {
|
||||
value_type y = (*Orb[iorb])(i,j,k);
|
||||
|
||||
//\warning: not protected for negative indices
|
||||
value_type y2x = ((*Orb[iorb])(i+1,j,k)+(*Orb[iorb])(i-1,j,k)-2.0*y)*drinv2[0];
|
||||
value_type y2y = ((*Orb[iorb])(i,j+1,k)+(*Orb[iorb])(i,j-1,k)-2.0*y)*drinv2[1];
|
||||
value_type y2z = ((*Orb[iorb])(i,j,k+1)+(*Orb[iorb])(i,j,k-1)-2.0*y)*drinv2[2];
|
||||
|
||||
if(xyz[ixyz][3]) {//positive
|
||||
value[iorb] += (Lx*Ly*Lz*y + Cx*Ly*Lz*y2x + Lx*Cy*Lz*y2y + Lx*Ly*Cz*y2z);
|
||||
lap[iorb] += Lx*Ly*Lz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
// Cvx = -dC/dx, Cvy = -dC/dy, and Cvz = -dC/dz
|
||||
// dL/dx = -1/dx
|
||||
gr[iorb][0] -= (drinv[0]*(Ly*Lz*y+Cy*Lz*y2y+Ly*Cz*y2z) + Cvx*Ly *Lz *y2x);
|
||||
gr[iorb][1] -= (drinv[1]*(Lz*Lx*y+Cz*Lx*y2z+Lz*Cx*y2x) + Lx *Cvy*Lz *y2y);
|
||||
gr[iorb][2] -= (drinv[2]*(Lx*Ly*y+Cx*Ly*y2x+Lx*Cy*y2y) + Lx *Ly *Cvz*y2z);
|
||||
|
||||
} else {
|
||||
value[iorb] -= (Lx*Ly*Lz*y +Cx*Ly*Lz*y2x + Lx*Cy*Lz*y2y + Lx*Ly*Cz*y2z);
|
||||
lap[iorb] -= Lx*Ly*Lz*(y2x+y2y+y2z);
|
||||
|
||||
// negative signs are taken care of here
|
||||
gr[iorb][0] += (drinv[0]*(Ly*Lz*y +Cy*Lz*y2y + Ly*Cz*y2z) + Cvx*Ly *Lz *y2x);
|
||||
gr[iorb][1] += (drinv[1]*(Lz*Lx*y +Cz*Lx*y2z + Lz*Cx*y2x) + Lx *Cvy*Lz *y2y);
|
||||
gr[iorb][2] += (drinv[2]*(Lx*Ly*y +Cx*Ly*y2x + Lx*Cy*y2y) + Lx *Ly *Cvz*y2z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class grid_type, class pos_type>
|
||||
void
|
||||
CubicSpline3D<grid_type,pos_type>::setxyz() {
|
||||
//4-bit to calculate the coefficient indices and sign
|
||||
//xyz[i](x,y,z,sign): initially, all the bits are set to 0
|
||||
//xyz[0] = bitset<4>(0,0,0,0); // -1(0) 3*0
|
||||
xyz[1].flip(2); xyz[1].flip(3); //xyz[1] = bitset<4>(0,0,1,1); // +1(1) 2*0
|
||||
xyz[2].flip(1); xyz[2].flip(2); //xyz[2] = bitset<4>(0,1,1,0); // -1(0) 1*0
|
||||
xyz[3].flip(1); xyz[3].flip(3); //xyz[3] = bitset<4>(0,1,0,1); // +1(1) 2*0
|
||||
xyz[4].flip(0); xyz[4].flip(3); //xyz[4] = bitset<4>(1,0,0,1); // +1(1) 2*0
|
||||
xyz[5].flip(0); xyz[5].flip(2); //xyz[5] = bitset<4>(1,0,1,0); // -1(0) 1*0
|
||||
xyz[6].flip(); //xyz[6] = bitset<4>(1,1,1,1); // +1(1) 0*0
|
||||
xyz[7].flip(0); xyz[7].flip(1); //xyz[7] = bitset<4>(1,1,0,0); // -1(0) 1*0
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,252 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
template<class T>
|
||||
T
|
||||
CubicSpline<T>::operator()(T r) {
|
||||
const T onesixth = 0.16666666666666666667e0;
|
||||
int klo,khi,k;
|
||||
T h,b,a;
|
||||
if(r>X[1] && r < X[Npt]) { //NR part
|
||||
klo=1;
|
||||
khi=Npt;
|
||||
while (khi-klo > 1) {
|
||||
k=(khi+klo) >> 1;
|
||||
if (X[k] > r) khi=k;
|
||||
else klo=k;
|
||||
}
|
||||
h=X[khi]-X[klo];
|
||||
if (h == 0.0) {
|
||||
// ERRORMSG("splint called with x = %lf\n",x);
|
||||
};
|
||||
a=(X[khi]-r)/h;
|
||||
b=(r-X[klo])/h;
|
||||
return a*Y[klo]+b*Y[khi]+
|
||||
(a*(a*a-1.e0)*Y2[klo]+b*(b*b-1.0e0)*Y2[khi])*(h*h)*onesixth;
|
||||
} else { // Extrapolation past endpoints
|
||||
if(r<=X[1]) {
|
||||
return Y[1] + Yp1 * (r - X[1]);
|
||||
}
|
||||
else{
|
||||
return Y[Npt] + Ypn * (r - X[Npt]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
CubicSpline<T>::operator()(T r, T& val) {
|
||||
|
||||
const T onesixth = 0.16666666666666666667e0;
|
||||
int klo,khi,k;
|
||||
T h,b,a;
|
||||
if(r>X[1] && r < X[Npt]) { //NR part
|
||||
klo=1;
|
||||
khi=Npt;
|
||||
while (khi-klo > 1) {
|
||||
k=(khi+klo) >> 1;
|
||||
if (X[k] > r) khi=k;
|
||||
else klo=k;
|
||||
}
|
||||
h=X[khi]-X[klo];
|
||||
if (h == 0.0) {
|
||||
//ERRORMSG("splint called with r = " << r << endl);
|
||||
};
|
||||
a=(X[khi]-r)/h;
|
||||
b=(r-X[klo])/h;
|
||||
val=a*Y[klo]+b*Y[khi]+
|
||||
(a*(a*a-1.e0)*Y2[klo]+b*(b*b-1.0e0)*Y2[khi])*(h*h)*onesixth;
|
||||
val /= r;
|
||||
return -(1/h)*(Y[klo]-Y[khi] + ((h*h)*onesixth)*((3*a*a-1)*Y2[klo] -
|
||||
(3*b*b-1)*Y2[khi]) );
|
||||
} else { // Extrapolation past endpoints
|
||||
if(r<=X[1]) {
|
||||
val =(Y[1] + Yp1 * (r - X[1]))/r;
|
||||
return Yp1;
|
||||
}
|
||||
else{
|
||||
val= (Y[Npt] + Ypn * (r - X[Npt]))/r;
|
||||
return Ypn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
CubicSpline<T>::operator()(T r, T& val, T& yp) {
|
||||
const T onesixth = 0.16666666666666666667e0;
|
||||
int klo,khi,k;
|
||||
T h,b,a;
|
||||
T rinv = 1.0/r;
|
||||
if(r>X[1] && r < X[Npt]) { //NR part
|
||||
klo=1;
|
||||
khi=Npt;
|
||||
while (khi-klo > 1) {
|
||||
k=(khi+klo) >> 1;
|
||||
if (X[k] > r) khi=k;
|
||||
else klo=k;
|
||||
}
|
||||
h=X[khi]-X[klo];
|
||||
if (h == 0.0) {
|
||||
//ERRORMSG("splint called with r = " << r << endl);
|
||||
};
|
||||
T hinv = 1/h;
|
||||
a=(X[khi]-r)*hinv;
|
||||
b=(r-X[klo])*hinv;
|
||||
val=a*Y[klo]+b*Y[khi]+
|
||||
(a*(a*a-1.e0)*Y2[klo]+b*(b*b-1.0e0)*Y2[khi])*(h*h)*onesixth;
|
||||
val *= (rinv*rinv);
|
||||
yp = -rinv*hinv*(Y[klo]-Y[khi] +
|
||||
(h*h*onesixth)*((3*a*a-1)*Y2[klo] -(3*b*b-1)*Y2[khi]) );
|
||||
|
||||
return a*Y2[klo]+b*Y2[khi];
|
||||
} else { // Extrapolation past endpoints
|
||||
if(r<=X[1]) {
|
||||
val =(Y[1] + Yp1 * (r - X[1]))*rinv*rinv;
|
||||
yp = Yp1*rinv;
|
||||
return 0.0e0;
|
||||
}
|
||||
else{
|
||||
val= (Y[Npt] + Ypn * (r - X[Npt]))*rinv*rinv;
|
||||
yp = Ypn*rinv;
|
||||
return 0.0e0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void CubicSpline<T>::spline() {
|
||||
//This is just a modified version of the Numerical Recipes routine spline,
|
||||
//which generates spline coefficients given a set of spline parameters.
|
||||
int i,k;
|
||||
T p,qn,sig,un;
|
||||
vector<T> u(Npt+1);
|
||||
|
||||
if (Yp1 > 0.99e30)
|
||||
Y2[1]=u[1]=0.0;
|
||||
else {
|
||||
Y2[1] = -0.5;
|
||||
u[1]=(3.0/(X[2]-X[1]))*((Y[2]-Y[1])/(X[2]-X[1])-Yp1);
|
||||
}
|
||||
for (i=2;i<=Npt-1;i++) {
|
||||
sig=(X[i]-X[i-1])/(X[i+1]-X[i-1]);
|
||||
p=sig*(Y2[i-1])+2.0;
|
||||
Y2[i]=(sig-1.0)/p;
|
||||
u[i]=(Y[i+1]-Y[i])/(X[i+1]-X[i]) - (Y[i]-Y[i-1])/(X[i]-X[i-1]);
|
||||
u[i]=(6.0*u[i]/(X[i+1]-X[i-1])-sig*u[i-1])/p;
|
||||
}
|
||||
if (Ypn > 0.99e30) qn=un=0.0;
|
||||
else {
|
||||
qn=0.5;
|
||||
un=(3.0/(X[Npt]-X[Npt-1]))*(Ypn-(Y[Npt]-Y[Npt-1])/(X[Npt]-X[Npt-1]));
|
||||
}
|
||||
Y2[Npt]=(un-qn*u[Npt-1])/(qn*(Y2[Npt-1])+1.0);
|
||||
for(k=Npt-1;k>=1;k--) Y2[k]= (Y2[k]*(Y2[k+1]))+u[k];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Regular spacing
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
T
|
||||
RegCubicSpline<T>::operator()(T r) {
|
||||
|
||||
if(r<Xmin) {
|
||||
return Y[1] + Yp1 * (r - Xmin);
|
||||
} else if(r<Xmax) {
|
||||
int i = static_cast<int>((r-Xmin)*DxInv+1);
|
||||
int ip = i+1;
|
||||
T rhi = static_cast<T>(i)*Dx+Xmin;
|
||||
T a=(rhi-r)*DxInv;
|
||||
T b=(r-rhi+Dx)*DxInv;
|
||||
return
|
||||
a*Y[i]+b*Y[ip]+(a*(a*a-1.e0)*Y2[i]+b*(b*b-1.0e0)*Y2[ip])*h2over6;
|
||||
} else {
|
||||
return Y[Npt] + Ypn * (r - Xmax);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
RegCubicSpline<T>::operator()(T r, T& val) {
|
||||
|
||||
if(r<Xmin) {
|
||||
val =(Y[1] + Yp1 * (r - Xmin))/r;
|
||||
return Yp1;
|
||||
} else if(r<Xmax) {
|
||||
int i = static_cast<int>((r-Xmin)*DxInv+1);
|
||||
int ip = i+1;
|
||||
T rhi = static_cast<T>(i)*Dx+Xmin;
|
||||
T a=(rhi-r)*DxInv;
|
||||
T b=(r-rhi+Dx)*DxInv;
|
||||
val = (a*Y[i]+b*Y[ip]+(a*(a*a-1.e0)*Y2[i]+b*(b*b-1.0e0)*Y2[ip])*h2over6)/r;
|
||||
return -DxInv*(Y[i] -Y[ip] + h2over6*((3*a*a-1)*Y2[i]-(3*b*b-1)*Y2[ip]));
|
||||
} else {
|
||||
val= (Y[Npt] + Ypn * (r - Xmax))/r;
|
||||
return Ypn;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
RegCubicSpline<T>::operator()(T r, T& val, T& yp) {
|
||||
T rinv = 1.0/r;
|
||||
if(r<Xmin) {
|
||||
val =(Y[1] + Yp1 * (r - Xmin))*rinv*rinv;
|
||||
yp = Yp1*rinv;
|
||||
return 0;
|
||||
} else if(r<Xmax) {
|
||||
int i = static_cast<int>((r-Xmin)*DxInv+1);
|
||||
int ip = i+1;
|
||||
T rhi = static_cast<T>(i)*Dx+Xmin;
|
||||
T a=(rhi-r)*DxInv;
|
||||
T b=(r-rhi+Dx)*DxInv;
|
||||
val = (a*Y[i]+b*Y[ip]
|
||||
+(a*(a*a-1.e0)*Y2[i]+b*(b*b-1.0e0)*Y2[ip])*h2over6)*rinv*rinv;
|
||||
yp = -rinv*DxInv*
|
||||
(Y[i] -Y[ip] + h2over6*((3*a*a-1)*Y2[i]-(3*b*b-1)*Y2[ip]));
|
||||
return a*Y2[i]+b*Y2[ip];
|
||||
} else {
|
||||
val= (Y[Npt] + Ypn * (r - Xmax))*rinv*rinv;
|
||||
yp = Ypn*rinv;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
RegCubicSpline<T>::spline() {
|
||||
//This is just a modified version of the Numerical Recipes routine spline,
|
||||
//which generates spline coefficients given a set of spline parameters.
|
||||
int i,k;
|
||||
T p,qn,sig,un;
|
||||
vector<T> u(Npt+1);
|
||||
|
||||
if (Yp1 > 0.99e30)
|
||||
Y2[1]=u[1]=0.0;
|
||||
else {
|
||||
Y2[1] = -0.5;
|
||||
u[1]=(3.0*DxInv)*((Y[2]-Y[1])*DxInv-Yp1);
|
||||
}
|
||||
sig=0.5;
|
||||
for (i=2;i<=Npt-1;i++) {
|
||||
p=sig*(Y2[i-1])+2.0;
|
||||
Y2[i]=(sig-1.0)/p;
|
||||
u[i]=(Y[i+1]+Y[i-1]-2*Y[i])*DxInv;
|
||||
u[i]=(3.0*u[i]*DxInv-sig*u[i-1])/p;
|
||||
}
|
||||
if (Ypn > 0.99e30) qn=un=0.0;
|
||||
else {
|
||||
qn=0.5;
|
||||
un=(3.0*DxInv)*(Ypn-(Y[Npt]-Y[Npt-1])*DxInv);
|
||||
}
|
||||
Y2[Npt]=(un-qn*u[Npt-1])/(qn*(Y2[Npt-1])+1.0);
|
||||
for(k=Npt-1;k>=1;k--) Y2[k]= (Y2[k]*(Y2[k+1]))+u[k];
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,102 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
|
||||
/***************************************************************************
|
||||
* This class implements the orthogonal tight-binding model
|
||||
* for Si proposed by Lenosky, Kress, Kwon, Voter, Edwards, Richards
|
||||
* Yang, and Adams in PRB 55 (1997) p.1528 using cubic splines
|
||||
* to parameterize hopping terms and pair-potential.
|
||||
* Implemented by D. Trinkle July '98 on TBMD
|
||||
* Implemented by Jeongnim Kim Sep '99
|
||||
***************************************************************************/
|
||||
#ifndef CUBICSPLINEFUNCTIONS_H
|
||||
#define CUBICSPLINEFUNCTIONS_H
|
||||
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
|
||||
template<class T>
|
||||
class CubicSpline{
|
||||
public:
|
||||
int Npt;
|
||||
T Yp1, Ypn;
|
||||
vector<T> X, Y, Y2;
|
||||
|
||||
CubicSpline() { }
|
||||
inline CubicSpline(const int n) { resize(n);}
|
||||
|
||||
inline void resize(const int n) {
|
||||
Npt = n;
|
||||
X = vector<T>(n+1); Y = vector<T>(n+1); Y2= vector<T>(n+1);
|
||||
}
|
||||
T operator()(T x0);
|
||||
T operator()(T x0, T& yval);
|
||||
T operator()(T x0, T& yval, T& yp);
|
||||
void spline();
|
||||
void spline(const int n, T* x, T* y, const T yp1, const T ypn){
|
||||
resize(n);
|
||||
X[0] = 0.0e0; Y[0] = 0.0e0; // not needed
|
||||
for(int i=1; i<=n; i++) X[i] = x[i-1];
|
||||
for(int i=1; i<=n; i++) Y[i] = y[i-1];
|
||||
Yp1 = yp1; Ypn = ypn;
|
||||
spline();
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class RegCubicSpline{
|
||||
int Npt;
|
||||
T Xmin, Xmax, Dx, DxInv;
|
||||
T Yp1, Ypn, h2over6;
|
||||
vector<T> Y, Y2;
|
||||
public:
|
||||
|
||||
RegCubicSpline() { }
|
||||
inline RegCubicSpline(const int n) { resize(n);}
|
||||
|
||||
inline void resize(const int n) {
|
||||
Npt = n;
|
||||
Y = vector<T>(n+1); Y2= vector<T>(n+1);
|
||||
}
|
||||
T operator()(T x0);
|
||||
T operator()(T x0, T& yval);
|
||||
T operator()(T x0, T& yval, T& yp);
|
||||
|
||||
void spline();
|
||||
void spline(const int n, const T x0, const T dx, const T yp1, const T ypn, T* y) {
|
||||
resize(n);
|
||||
Dx = dx; DxInv = 1/dx;
|
||||
h2over6 = dx*dx*0.16666666666666666667e0;
|
||||
Xmin = x0; Xmax = static_cast<T>(n-1)*dx+x0;
|
||||
Y[0] = 0;
|
||||
for(int i=1; i<=n; i++) Y[i] = y[i-1];
|
||||
|
||||
Yp1 = yp1;
|
||||
Ypn = ypn;
|
||||
spline();
|
||||
}
|
||||
};
|
||||
|
||||
#include "ScaleFunctors/CubicSplineFunctions.cpp"
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* POOMA_VERSION_ID: $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,161 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
#ifndef OHMMS_NUMERIC_DETERMINANT_H
|
||||
#define OHMMS_NUMERIC_DETERMINANT_H
|
||||
|
||||
#include <algorithm>
|
||||
#include "OhmmsPETE/OhmmsVector.h"
|
||||
#include "OhmmsPETE/OhmmsMatrix.h"
|
||||
#include "Numerics/Blasf.h"
|
||||
|
||||
inline void LUFactorization(const int& n, const int& m, double* a, const int& n0,
|
||||
int* piv) {
|
||||
int status;
|
||||
dgetrf(n,m,a,n0,piv,status);
|
||||
}
|
||||
|
||||
inline void LUFactorization(const int& n, const int& m, complex<double>* a, const int& n0,
|
||||
int* piv) {
|
||||
int status;
|
||||
zgetrf(n,m,a,n0,piv,status);
|
||||
}
|
||||
|
||||
inline void InvertLU(const int& n, double* a, const int& n0,
|
||||
int* piv, double* work, const int& n1){
|
||||
int status;
|
||||
dgetri(n,a,n0,piv,work,n1,status);
|
||||
}
|
||||
|
||||
inline double Invert(double* x, int n, int m) {
|
||||
double detvalue;
|
||||
if(n == 1) {
|
||||
detvalue = x[0];
|
||||
x[0]=1.0/detvalue;
|
||||
} else {
|
||||
vector<double> work(n);
|
||||
vector<int> pivot(n);
|
||||
LUFactorization(n,m,x,n,&pivot[0]);
|
||||
detvalue = x[0];
|
||||
for (int i=1; i<m; ++i) detvalue *= x[i*m+i];
|
||||
InvertLU(n,x, n, &pivot[0], &work[0], n);
|
||||
}
|
||||
/*
|
||||
switch(n) {
|
||||
case(1):
|
||||
detvalue = x[0];
|
||||
x[0]=1.0/detvalue;break;
|
||||
case(2):
|
||||
detvalue = x[0] * x[3] - x[1] * x[2];
|
||||
double deti = 1.0/detvalue;
|
||||
x[0] = deti*x[3];
|
||||
x[1]*=-deti;
|
||||
x[2]*=-deti;
|
||||
x[3] = deti*x[0];
|
||||
break;
|
||||
defaults:
|
||||
cout << "using generic inversion " << endl;
|
||||
vector<double> work(n);
|
||||
vector<int> pivot(n);
|
||||
LUFactorization(n,m,x,n,&pivot[0]);
|
||||
for (int i=1; i<m; ++i) detvalue *= x[i*m+i];
|
||||
InvertLU(n,x, n, &pivot[0], &work[0], n);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
// if(n == 1) {
|
||||
// x[0]=1.0/detvalue;
|
||||
// } else {
|
||||
// vector<double> work(n);
|
||||
// vector<int> pivot(n);
|
||||
// LUFactorization(n,m,x,n,&pivot[0]);
|
||||
// for (int i=1; i<m; ++i) detvalue *= x[i*m+i];
|
||||
// InvertLU(n,x, n, &pivot[0], &work[0], n);
|
||||
// }
|
||||
return detvalue;
|
||||
}
|
||||
/*!\fn invert_matrix(MatrixA& M, bool getdet)
|
||||
* \param MatrixA, a matrix to be inverted
|
||||
* \param bool, if true, calculate the determinant
|
||||
* \return the determinant
|
||||
*/
|
||||
template<class MatrixA>
|
||||
inline double
|
||||
invert_matrix(MatrixA& M, bool getdet=true) {
|
||||
|
||||
typedef typename MatrixA::value_type value_type;
|
||||
Vector<int> pivot(M.rows());
|
||||
Vector<value_type> work(M.rows());
|
||||
int status;
|
||||
|
||||
dgetrf(M.rows(), M.cols(), M.data(), M.rows(), pivot.data(), status);
|
||||
|
||||
value_type det0 = 1.0;
|
||||
|
||||
if(getdet) {// calculate determinant
|
||||
int sign = 1;
|
||||
for(int i=0; i<M.rows(); ++i){
|
||||
if(pivot[i] != i+1) sign *= -1;
|
||||
det0 *= M(i,i);
|
||||
}
|
||||
det0 *= static_cast<value_type>(sign);
|
||||
}
|
||||
|
||||
dgetri(M.rows(), M.data(), M.rows(), pivot.data(), work.data(),
|
||||
M.rows(), status);
|
||||
return det0;
|
||||
}
|
||||
|
||||
template<class MatA, class Iter>
|
||||
inline
|
||||
typename MatA::value_type
|
||||
DetRatio(const MatA& Minv, Iter newrow, int rowchanged) {
|
||||
typename MatA::value_type res = 0.0;
|
||||
for(int j=0; j<Minv.cols(); j++,newrow++)
|
||||
res += Minv(rowchanged,j)*(*newrow);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T, unsigned D>
|
||||
inline TinyVector<T,D>
|
||||
dot(const T* a, const TinyVector<T,D>* b, int n) {
|
||||
TinyVector<T,D> res;
|
||||
for(int i=0; i<n; i++) res += a[i]*b[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T dot(const T* restrict a, const T* restrict b, int n) {
|
||||
T res = 0.0;
|
||||
for(int i=0; i<n; i++) res += a[i]*b[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
// template<class T1, class T2>
|
||||
// inline T2
|
||||
// dot(const T1* restrict a, const T2* restrict b, int n) {
|
||||
// T2 res;
|
||||
// for(int i=0; i<n; i++) res += a[i]*b[i];
|
||||
// return res;
|
||||
// }
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,64 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_SLATERTYPEORBITAL_H
|
||||
#define OHMMS_SLATERTYPEORBITAL_H
|
||||
#include <math.h>
|
||||
|
||||
/**class for Gaussian-type orbitals
|
||||
*@f[
|
||||
*\Psi_{n,l,m}({\bf R}) =N \frac{\exp{-\sigma r^2}}{r^l} \times r^l Y_{lm}(\theta,\phi)
|
||||
*@f]
|
||||
*/
|
||||
template<class T>
|
||||
struct RadialGaussian {
|
||||
int L;
|
||||
T Sigma;
|
||||
T Norm;
|
||||
RadialGaussian(): L(0), Sigma(1.0), Norm(1.0) { }
|
||||
RadialGaussian(int l, double sig, double norm=1.0): L(l), Sigma(sig),Norm(norm) { }
|
||||
|
||||
inline void setgrid(T r) { }
|
||||
|
||||
inline void evaluate(T r, T rinv) {
|
||||
Y = evaluate(r,rinv,dY,d2Y);
|
||||
}
|
||||
inline T evaluate(T r, T rinv, T& drnl, T& d2rnl) {
|
||||
if(L) {
|
||||
T oneoverrl = pow(rinv,L);
|
||||
T rnl = Norm*exp(-Sigma*r*r)*oneoverrl;
|
||||
T x = 2.0*Sigma*r+L*rinv;
|
||||
drnl = -rnl*x;
|
||||
d2rnl = rnl*(x*x-2.0*Sigma+L*rinv*rinv);
|
||||
return rnl;
|
||||
} else {
|
||||
T rnl = Norm*exp(-Sigma*r*r);
|
||||
T x = 2.0*Sigma*r;
|
||||
drnl = -rnl*x;
|
||||
d2rnl = rnl*(x*x-2.0*Sigma);
|
||||
return rnl;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,316 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_HDF_NUMERICATTRIBIO_H
|
||||
#define OHMMS_HDF_NUMERICATTRIBIO_H
|
||||
#include "OhmmsData/HDFAttribIO.h"
|
||||
#include "OhmmsPETE/OhmmsVector.h"
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include "OhmmsPETE/OhmmsMatrix.h"
|
||||
#include <blitz/array.h>
|
||||
|
||||
/** Specialization for hsize_t */
|
||||
template<>
|
||||
struct HDFAttribIO<hsize_t>: public HDFAttribIOBase {
|
||||
|
||||
hsize_t& ref;
|
||||
|
||||
HDFAttribIO<hsize_t>(hsize_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
hsize_t dim = 1;
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_INT, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,&ref);
|
||||
H5Sclose(dataspace);
|
||||
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref);
|
||||
H5Dclose(h1);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
template<unsigned D>
|
||||
struct HDFAttribIO<TinyVector<double,D> >: public HDFAttribIOBase {
|
||||
|
||||
typedef TinyVector<double,D> data_type;
|
||||
|
||||
data_type& ref;
|
||||
|
||||
HDFAttribIO<data_type>(data_type& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
hsize_t dim = D;
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,&(ref[0]));
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(ref[0]));
|
||||
H5Dclose(h1);
|
||||
}
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
/** Specialization for Vector<double> */
|
||||
template<>
|
||||
struct HDFAttribIO<Vector<double> >: public HDFAttribIOBase {
|
||||
|
||||
typedef Vector<double> ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
|
||||
hsize_t dim = ref.size();
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t dataspace = H5Dget_space(h1);
|
||||
hsize_t dims_out[1];
|
||||
int rank = H5Sget_simple_extent_ndims(dataspace);
|
||||
int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
|
||||
if(ref.size() != int(dims_out[0])){
|
||||
ref.resize(int(dims_out[0]));
|
||||
}
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Specialization for Vector<int> */
|
||||
template<>
|
||||
struct HDFAttribIO<Vector<int> >: public HDFAttribIOBase {
|
||||
|
||||
typedef Vector<int> ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
|
||||
hsize_t dim = ref.size();
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_INT, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t dataspace = H5Dget_space(h1);
|
||||
hsize_t dims_out[1];
|
||||
int rank = H5Sget_simple_extent_ndims(dataspace);
|
||||
int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
|
||||
if(ref.size() != int(dims_out[0])){
|
||||
ref.resize(int(dims_out[0]));
|
||||
}
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Specialization for Matrix<double> */
|
||||
template<>
|
||||
struct HDFAttribIO<Matrix<double> >: public HDFAttribIOBase {
|
||||
|
||||
typedef Matrix<double> ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
hsize_t dim = ref.size();
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref.data());
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Specialization for blitz::Array<TinyVector<double,D>,2> */
|
||||
template<unsigned D>
|
||||
struct HDFAttribIO<blitz::Array<TinyVector<double,D>,2> >: public HDFAttribIOBase {
|
||||
|
||||
typedef blitz::Array<TinyVector<double,D>,2> ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
int rank = 3;
|
||||
hsize_t dim[rank];
|
||||
dim[0] = ref.extent(0);
|
||||
dim[1] = ref.extent(1);
|
||||
dim[2] = D;
|
||||
hid_t dataspace = H5Screate_simple(rank, dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t dataspace = H5Dget_space(h1);
|
||||
hsize_t dims_out[3];
|
||||
int rank = H5Sget_simple_extent_ndims(dataspace);
|
||||
int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
|
||||
if((ref.extent(0) != (unsigned long)dims_out[0]) || (ref.extent(1) != (unsigned long)dims_out[1])){
|
||||
// cout << "dimensions not equal" << endl;
|
||||
ref.resize(dims_out[0],dims_out[1]);
|
||||
}
|
||||
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref.data());
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Specialization for Vector<TinyVector<double,D> > */
|
||||
template<unsigned D>
|
||||
struct HDFAttribIO<Vector<TinyVector<double,D> > >: public HDFAttribIOBase {
|
||||
|
||||
typedef Vector<TinyVector<double,D> > ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a):ref(a) { }
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
hsize_t dim[2] = {ref.size(), D};
|
||||
hid_t dataspace = H5Screate_simple(2, dim, NULL);
|
||||
hid_t dataset =
|
||||
H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t dataspace = H5Dget_space(h1);
|
||||
hsize_t dims_out[2];
|
||||
int rank = H5Sget_simple_extent_ndims(dataspace);
|
||||
int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
|
||||
if(ref.size() != (unsigned long)dims_out[0]){
|
||||
// cout << "dimensions not equal" << endl;
|
||||
ref.resize(dims_out[0]);
|
||||
}
|
||||
hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref.data());
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Specialization for string */
|
||||
template<>
|
||||
struct HDFAttribIO<string>: public HDFAttribIOBase {
|
||||
|
||||
typedef string ArrayType_t;
|
||||
ArrayType_t& ref;
|
||||
hid_t str80;
|
||||
|
||||
HDFAttribIO<ArrayType_t>(ArrayType_t& a): ref(a) {
|
||||
str80 = H5Tcopy(H5T_C_S1);
|
||||
H5Tset_size(str80,80);
|
||||
}
|
||||
|
||||
inline void write(hid_t grp, const char* name) {
|
||||
|
||||
hsize_t dim = 1;
|
||||
hid_t dataspace = H5Screate_simple(1, &dim, NULL);
|
||||
hid_t dataset =
|
||||
// H5Dcreate(grp, name, H5T_NATIVE_CHAR, dataspace, H5P_DEFAULT);
|
||||
H5Dcreate(grp, name, str80, dataspace, H5P_DEFAULT);
|
||||
hid_t ret =
|
||||
// H5Dwrite(dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Dwrite(dataset, str80, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref.data());
|
||||
H5Sclose(dataspace);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
inline void read(hid_t grp, const char* name) {
|
||||
hid_t h1 = H5Dopen(grp, name);
|
||||
hid_t dataspace = H5Dget_space(h1);
|
||||
hsize_t dims_out[1];
|
||||
// int rank = H5Sget_simple_extent_ndims(dataspace);
|
||||
// int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
|
||||
// if(ref.size() != (unsigned long)dims_out[0]){
|
||||
// cout << "dimensions not equal" << endl;
|
||||
// ref.resize(dims_out[0]);
|
||||
// }
|
||||
hid_t ret = H5Dread(h1, str80, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref);
|
||||
H5Dclose(h1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,46 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 1998-2002 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_LIBXML_NUMERICATTRIBIO_H
|
||||
#define OHMMS_LIBXML_NUMERICATTRIBIO_H
|
||||
#include "OhmmsData/libxmldefs.h"
|
||||
#include "OhmmsPETE/OhmmsVector.h"
|
||||
#include "OhmmsPETE/OhmmsMatrix.h"
|
||||
/*!\fn bool putContent(std::Matrix<T>& a, xmlNodePtr cur)
|
||||
*\brief assign vector<T> from a node. Create a temporary vector and make assignment.
|
||||
*\param a reference vector<T>
|
||||
*\param cur current node to which a content is copied
|
||||
*\return ture if successful
|
||||
*/
|
||||
template<class T>
|
||||
inline bool
|
||||
putContent(Matrix<T>& a, xmlNodePtr cur){
|
||||
std::istringstream
|
||||
stream((const char*)
|
||||
(xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1)));
|
||||
int i=0;
|
||||
while(!stream.eof()){ stream >> a(i++);}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,84 @@
|
|||
#ifndef GUARD_MATGRID1D_H
|
||||
#define GUARD_MATGRID1D_H
|
||||
#include <vector>
|
||||
#include "Numerics/Spline3D/Config.h"
|
||||
#include "Numerics/Spline3D/Grid1D.h"
|
||||
|
||||
|
||||
class MatGrid1D{
|
||||
|
||||
public:
|
||||
|
||||
/// number of different grid density sections (regions)
|
||||
int nsecs_m;
|
||||
|
||||
/// starting coordinate of grid
|
||||
int ix0_m;
|
||||
|
||||
/// the axis of the grid: namely the z direction z = 2;
|
||||
int iaxis;
|
||||
|
||||
/// the vector containing the intervals and properties
|
||||
std::vector<int> d_ivals;
|
||||
std::vector<int> prior_m;
|
||||
std::vector<double> prop_m;
|
||||
std::vector<double> dx_ivals;
|
||||
|
||||
|
||||
/// the constructor
|
||||
MatGrid1D(int nsections){
|
||||
|
||||
nsecs_m = nsections;
|
||||
d_ivals.resize(nsecs_m+1);
|
||||
dx_ivals.resize(nsecs_m+1);
|
||||
prop_m.resize(nsecs_m);
|
||||
prior_m.resize(nsecs_m);
|
||||
|
||||
cout << "material Grid:" << nsecs_m << endl;
|
||||
|
||||
}
|
||||
|
||||
/// initialise with the entire data from input
|
||||
inline void init(const Grid1D& aGrid1D,
|
||||
const std::vector<int>& ix,
|
||||
const std::vector<int>& prior,
|
||||
const std::vector<double>& props){
|
||||
|
||||
d_ivals[0] = 0; dx_ivals[0] = aGrid1D.d_x[d_ivals[0]];
|
||||
for( int isec = 0; isec < prop_m.size(); isec++){
|
||||
d_ivals[isec+1] = ix[isec+1];
|
||||
dx_ivals[isec+1] = aGrid1D.d_x[d_ivals[isec+1]];
|
||||
prop_m[isec] = props[isec];
|
||||
prior_m[isec] = prior[isec];
|
||||
}
|
||||
}
|
||||
|
||||
/// get the property of the material
|
||||
inline double prop(double x){
|
||||
|
||||
double property; bool flag=true;
|
||||
for(int isec = 0; isec < nsecs_m; isec++){
|
||||
double xsec = dx_ivals[isec+1];
|
||||
if( flag && x < xsec ){
|
||||
property = prop_m[isec]; flag = false;
|
||||
} else if( flag && x == xsec ){
|
||||
int jsec = (prior_m[isec+1] > prior_m[isec]) ? isec + 1 : isec;
|
||||
property = prop_m[jsec];
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
return property;
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_NR_CUBICSPLINE_H
|
||||
#define OHMMS_NR_CUBICSPLINE_H
|
||||
/**template function: converted from Numerical Recipe spline.c
|
||||
*note that the range of data is [0,n) instead of [1,n]
|
||||
*/
|
||||
template<class T>
|
||||
inline void
|
||||
NRCubicSpline(const T* x, const T* y, int n, T yp1, T ypn, T* y2) {
|
||||
|
||||
int i,k;
|
||||
T p,qn,sig,un;
|
||||
vector<T> u(n);
|
||||
if (yp1 > 0.99e30)
|
||||
y2[0]=u[0]=0.0;
|
||||
else {
|
||||
y2[0] = -0.5;
|
||||
u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yp1);
|
||||
}
|
||||
for (i=1;i<n-1;i++) {
|
||||
sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]);
|
||||
p=sig*y2[i-1]+2.0;
|
||||
y2[i]=(sig-1.0)/p;
|
||||
u[i]=(y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]);
|
||||
u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p;
|
||||
}
|
||||
if (ypn > 0.99e30)
|
||||
qn=un=0.0;
|
||||
else {
|
||||
qn=0.5;
|
||||
un=(3.0/(x[n-1]-x[n-2]))*(ypn-(y[n-1]-y[n-2])/(x[n-1]-x[n-2]));
|
||||
}
|
||||
y2[n-1]=(un-qn*u[n-2])/(qn*y2[n-2]+1.0);
|
||||
for (k=n-2;k>=0;k--)
|
||||
y2[k]=y2[k]*y2[k+1]+u[k];
|
||||
}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,287 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim and Jordan Vincent
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef NUMEROVCLASS_H
|
||||
#define NUMEROVCLASS_H
|
||||
|
||||
/**@defgroup NumerovTransform
|
||||
*@brief Transform functors which provide interfaces to Numerov<ST,FT>.
|
||||
*
|
||||
*The prototype: "template<class SourceType> ATransformFunctor",
|
||||
*where SourceType encapsulates the form of an external potential.
|
||||
*
|
||||
*For examples, the RegularLinearTransform is implemented to solve
|
||||
*Radial Schrodinger equation
|
||||
*\f[ \frac{d^2R_{nl}}{dr^2}+k^2(r) R_{nl} = 0, \f] where
|
||||
*\f[k^2(r)=2[\varepsilon-\frac{L(L+1)}{2r^2}-V(r)], \f] and
|
||||
*\f$ V(r) \f$ is a radial potential on a linear grid.
|
||||
*
|
||||
*/
|
||||
/** Generic class to solve eigen problems using the Numerov
|
||||
*Integration Algorithm.
|
||||
*
|
||||
*Solve second order differential equations of the form
|
||||
\f[\frac{d^2y}{dx^2} + k^2(x)y = S(x)\f]
|
||||
using the Numerov algorithm
|
||||
\f[
|
||||
(1+\frac{h^2}{12}k^2_{n+2})y_{n+2} -
|
||||
2(1-\frac{5h^2}{12}k^2_{n+1})y_{n+1} + (1+\frac{h^2}{12}k^2_n)y_n =
|
||||
\frac{h^2}{12}(S_{n+2}+10S_{n+1}+S_n) + \mathcal{O}(h^6), \f] by
|
||||
solving for \f$y_{n+2}\f$ and recursively integrating forward in x.
|
||||
The boundary conditons being \f$y_0 = y(x_0)\f$ and \f$y_1 = y(x_1).\f$
|
||||
*
|
||||
* Two template parameters are required:
|
||||
- ST: source functor type, e.g., the transform functors in
|
||||
\ref NumerovTransform.
|
||||
- FT: grid functor type for the solution \f$y(x)\f$ and \f$V(x)\f$
|
||||
for \f$k^2(\epsilon,V(x))\f$.
|
||||
*
|
||||
*See \ref numerov_sec "Numerov algorihm".
|
||||
*
|
||||
*Specifically, the source functor should implement
|
||||
- value_type ST::setCusp(int i, value_type& z0, value_type& z1)
|
||||
- int ST::first() the first valid index for the grid
|
||||
- value_type ST::ke(i)
|
||||
- value_type ST::convert(value_type Z(x), x)
|
||||
*
|
||||
*/
|
||||
template<class ST, class FT>
|
||||
class Numerov {
|
||||
|
||||
public:
|
||||
|
||||
enum {lower_energy=-1, nothing, raise_energy};
|
||||
|
||||
typedef typename FT::value_type value_type;
|
||||
typedef typename FT::data_type data_type;
|
||||
|
||||
///constructor with source V(x) and target solution f(x) and TransForm y
|
||||
Numerov(ST& y, FT& f): Y(y), Target(f) {
|
||||
|
||||
Z.resize(Target.size());
|
||||
//save the derivate of the first grid
|
||||
Y.setCusp(Y.first(), Target0, Target1);
|
||||
}
|
||||
|
||||
int evaluate(value_type e);
|
||||
|
||||
/**
|
||||
*\param lowerin lower bound for the eigen energy
|
||||
*\param upperin upper bound for the eigen energy
|
||||
*\param etol the energy tolerance
|
||||
*\return the eigen energy
|
||||
*\brief Solve for the eigen energy and eigen function self
|
||||
consistently.
|
||||
*/
|
||||
inline value_type solve(value_type lowerin, value_type upperin,
|
||||
value_type etol) {
|
||||
|
||||
value_type lower = lowerin;
|
||||
value_type upper = upperin;
|
||||
|
||||
value_type trialenergy=0.5*(lower+upper);
|
||||
value_type oldenergy = upper;
|
||||
int modifier = nothing;
|
||||
do{
|
||||
modifier = evaluate(trialenergy);
|
||||
if(modifier == raise_energy) lower = trialenergy;
|
||||
if(modifier == lower_energy) upper = trialenergy;
|
||||
oldenergy = trialenergy;
|
||||
trialenergy=0.5*(lower+upper);
|
||||
} while((fabs(trialenergy-oldenergy))>etol);
|
||||
return trialenergy;
|
||||
}
|
||||
|
||||
/**
|
||||
*\param e reference eigenvalue
|
||||
*\brief Reset the reference eigen energy for \f$k^2(\epsilon, V(x))\f$
|
||||
*and the classical TurningPoint \f$i\f$, where
|
||||
*\f$k^2(\epsilon,V(x_{i})) < 0\f$ and \f$k^2(\epsilon,V(x_{i-1})) > 0\f$
|
||||
*/
|
||||
inline void reset(value_type e) {
|
||||
Target.m_Y = 0.0;
|
||||
TurningPoint = 0;
|
||||
Y.reset(e);
|
||||
int i=Target.size()-2;
|
||||
while(i > 1 && Y.ke(i)<0) {
|
||||
i--;
|
||||
}
|
||||
TurningPoint = i;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
///engine that takes care of the transformation of variables
|
||||
ST& Y;
|
||||
|
||||
///real function that holds solution
|
||||
FT& Target;
|
||||
|
||||
///solution by Numerov Target <-> TransForm::convert(Z)
|
||||
data_type Z;
|
||||
|
||||
///cusp condition
|
||||
value_type Target0, Target1;
|
||||
|
||||
///the maximum size of physical data
|
||||
int TurningPoint;
|
||||
|
||||
///index reserved to truncate the data
|
||||
int Current;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*\param e reference eigen energy for \f$k^2(\epsilon, V(x))\f$
|
||||
*\return integer flag for the change of the reference eigen energy
|
||||
*/
|
||||
template<class TransForm, class FT>
|
||||
inline
|
||||
int Numerov<TransForm,FT>::evaluate(value_type e) {
|
||||
|
||||
reset(e);
|
||||
|
||||
const value_type MAX_VALUE = 1000;
|
||||
|
||||
value_type dh2 = Target.dh()*Target.dh();
|
||||
value_type tentwelfth = 0.8333333333333333333333333333333333333333333333*dh2;
|
||||
value_type onetwelfth = 0.0833333333333333333333333333333333333333333333*dh2;
|
||||
|
||||
//get the first index
|
||||
int first = Y.first();
|
||||
int second = first+1;
|
||||
Z[first] = Target0;
|
||||
Z[second] = Target1;
|
||||
|
||||
value_type r0 = Target.r(first);
|
||||
value_type r1 = Target.r(second);
|
||||
value_type ke_m2 = Y.ke(first);
|
||||
value_type ke_m = Y.ke(second);
|
||||
|
||||
value_type y_m2 = Z[first];
|
||||
value_type y_m = Z[second];
|
||||
|
||||
//set the wave function
|
||||
Target(first) = Y.convert(y_m2,r0);
|
||||
Target(second) = Y.convert(y_m,r1);
|
||||
|
||||
int num_nodes = 0;
|
||||
int nodes_to_find = Y.nodes();
|
||||
|
||||
//not meaningful turning point, raise the energy
|
||||
if(TurningPoint == 1) return raise_energy;
|
||||
|
||||
int e_mode =nothing;
|
||||
|
||||
int i=first+2;
|
||||
while(i<=TurningPoint+2) {
|
||||
|
||||
//get the radius of the current index
|
||||
r0 = Target.r(i);
|
||||
|
||||
//get k^2
|
||||
value_type ke = Y.ke(i);
|
||||
value_type y =
|
||||
((2.0-tentwelfth*ke_m)*y_m -
|
||||
(1.0+onetwelfth*ke_m2)*y_m2)/(1.0+onetwelfth*ke);
|
||||
|
||||
Z[i] = y;
|
||||
|
||||
//avoid exponential solution
|
||||
if(fabs(y)>MAX_VALUE) {
|
||||
value_type yinv = 1.0/y;
|
||||
for(int j=0; j<=i; j++) Z[j]*=yinv;
|
||||
y_m2*=yinv;
|
||||
y_m*=yinv;
|
||||
y = 1.0;
|
||||
|
||||
}
|
||||
|
||||
//check the node
|
||||
if(y_m*y < 0.0) {
|
||||
num_nodes++;
|
||||
if( num_nodes > nodes_to_find) {
|
||||
return lower_energy;
|
||||
}
|
||||
}
|
||||
|
||||
ke_m2 = ke_m;
|
||||
ke_m = ke;
|
||||
|
||||
y_m2 = y_m;
|
||||
y_m = y;
|
||||
|
||||
Target(i) = Y.convert(Z[i],r0);
|
||||
i++;
|
||||
}
|
||||
|
||||
if(e_mode == nothing) {
|
||||
|
||||
i = TurningPoint+3;
|
||||
|
||||
while(i<=Target.size()-2) {
|
||||
|
||||
r0 = Target.r(i);
|
||||
//get k^2
|
||||
value_type ke = Y.ke(i);
|
||||
value_type y
|
||||
= ((2.0-tentwelfth*ke_m)*y_m - (1.0+onetwelfth*ke_m2)*y_m2)
|
||||
/(1.0+onetwelfth*ke);
|
||||
|
||||
Z[i] = y;
|
||||
|
||||
//growing beyond the turning point
|
||||
if(y/y_m > 1) {
|
||||
return raise_energy;
|
||||
}
|
||||
|
||||
if(fabs(y)>MAX_VALUE) {
|
||||
value_type yinv = 1.0/y;
|
||||
for(int j=0; j<=i; j++) Z[j]*=yinv;
|
||||
y_m2*=yinv;
|
||||
y_m*=yinv;
|
||||
y = 1.0;
|
||||
}
|
||||
|
||||
if(y_m*y < 0.0) {
|
||||
num_nodes++;
|
||||
if(num_nodes > nodes_to_find) return lower_energy;
|
||||
}
|
||||
|
||||
//assign numerov value to the real function
|
||||
ke_m2 = ke_m;
|
||||
ke_m = ke;
|
||||
|
||||
y_m2 = y_m;
|
||||
y_m = y;
|
||||
|
||||
Target(i) = Y.convert(Z[i],r0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if( num_nodes < nodes_to_find )
|
||||
return raise_energy;
|
||||
else
|
||||
return nothing;
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,223 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_GRID_FUNCTOR_CUBIC_SPLINE_H
|
||||
#define OHMMS_GRID_FUNCTOR_CUBIC_SPLINE_H
|
||||
|
||||
#include "Numerics/OneDimGridFunctor.h"
|
||||
#include "Numerics/NRSplineFunctions.h"
|
||||
|
||||
|
||||
/**Perform One-Dimensional Cubic Spline Interpolation.
|
||||
*
|
||||
Given a function evaluated on a grid \f$ \{x_i\},
|
||||
i=1\ldots N, \f$ such that \f$ y_i = y(x_i), \f$ we would like to
|
||||
interpolate for a point \f$ x \f$ in the interval \f$ [x_j,x_{j+1}]. \f$
|
||||
The linear interpolation formula
|
||||
\f[
|
||||
y = Ay_j + By_{j+1}
|
||||
\f]
|
||||
where
|
||||
\f[
|
||||
A = \frac{x_{j+1}-x}{x_{j+1}-x_j} \;\;\;\;\;\;\;\;\;\;\;\;\;
|
||||
B = 1-A = \frac{x-x_{j+1}}{x_{j+1}-x_j}
|
||||
\f]
|
||||
Satisfies the conditions at the endpoints \f$ x_j \mbox{ and } x_{j+1},\f$
|
||||
but suffers from some major drawbacks. The problem with this approach is
|
||||
that over the range of the function \f$ [x_1,x_N] \f$ we have a series of
|
||||
piecewise linear equations with a zero second derivative within each interval
|
||||
and an undefined or infinite second derivative at the interval boundaries,
|
||||
the grid points \f$ \{x_i\}. \f$ Ideally we would like to construct an
|
||||
interpolation function with a smooth first derivate and a continuous second
|
||||
derivative both within the intervals and at the the grid points.
|
||||
|
||||
By adding a cubic polynomial to the linear interpolation equation within
|
||||
each interval, we can construct an interpolation function that varies
|
||||
linearly in the second derivative. Assume for a moment that we have the
|
||||
values of the second derivative evaluated at each grid point,
|
||||
\f$ y_i'' = d^2y(x_i)/dx^2, i=1\ldots N. \f$ Now we can construct a cubic
|
||||
polynomial that has the correct second derivatives \f$y_j'' \mbox{ and }
|
||||
y_{j+1}''\f$ at the endpoints and also evaluates to zero at the endpoints.
|
||||
The reason the polynomial must be zero at the endpoints is to not spoil
|
||||
the agreement that is already built into the linear function. A function
|
||||
constructed from these principals is given by the equation
|
||||
\f[
|
||||
y = Ay_j + By_{j+1} + Cy_j'' + Dy_{j+1}''
|
||||
\f]
|
||||
where
|
||||
\f[
|
||||
C = \frac{1}{6}(A^3-A)(x_{j+1}-x_j)^2 \;\;\;\;\;\;\;
|
||||
D = \frac{1}{6}(B^3-B)(x_{j+1}-x_j)^2.
|
||||
\f]
|
||||
|
||||
|
||||
To explictly check that this function does indeed satisfy the conditions
|
||||
at the endpoints take the derivatives
|
||||
\f[
|
||||
\frac{dy}{dx} = \frac{y_{j+1}-y_j}{x_{j+1}-x_j}
|
||||
- \frac{3A^2-1}{6}(x_{j+1}-x_j)y_j''
|
||||
+ \frac{3B^2-1}{6}(x_{j+1}-x_j)y_{j+1}''
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\frac{d^2y}{dx^2} = Ay_j'' + By_{j+1}''.
|
||||
\f]
|
||||
The second derivative is continuous across the boundary between two
|
||||
intervals, e.g. \f$ [x_{j-1},x_j] \f$ and \f$ [x_j,x_{j+1}], \f$ and
|
||||
obeys the conditions at the endpoints since at \f$ x=x_j, (A=1,B=0) \f$
|
||||
and at \f$ x=x_{j+1}, (A=0,B=1). \f$
|
||||
|
||||
|
||||
We had made the assumption that the values of the second derivative are
|
||||
known at the grid points, which they are not. By imposing the condition
|
||||
that the first derivative is smooth and continuous across the boundary
|
||||
between two intervals it is possible to derive a set of equations to
|
||||
generate the \f$ y_i''\f$'s. Evaluate the equation for the first
|
||||
derivative at \f$x=x_j\f$ in the inverval \f$ [x_{j-1},x_j] \f$ and set
|
||||
it equal to the same equation evaluated at \f$x=x_j\f$ in the inverval
|
||||
\f$ [x_j,x_{j+1}]; \f$ rearranging the terms
|
||||
|
||||
\f[
|
||||
\frac{x_j-x_{j+1}}{6}y_{j+1}'' + \frac{x_{j+1}-x_{j-1}}{3}y_j''
|
||||
+ \frac{x_{j+1}-x_j}{6}y_{j+1}'' = \frac{y_{j+1}-y_j}{x_{j+1}-x_j}
|
||||
- \frac{y_j-y_{j+1}}{x_j-x_{j+1}},
|
||||
\f]
|
||||
where \f$ j=2\ldots N-1.\f$ To generate a unique solution for the system
|
||||
of \f$N-2\f$ equations we have to impose boundary conditions at \f$x_1
|
||||
\mbox{ and } x_N,\f$ the possibilities being either to set \f$y_1''
|
||||
\mbox{ and } y_N''\f$ to zero, the natural cubic spline, or, if you want
|
||||
to make the first derivative at the boundaries to have a specified value,
|
||||
use \f$y_1' \mbox{ and } y_N'\f$ to calculate the second derivatives at
|
||||
the endpoints using equation.
|
||||
*
|
||||
*/
|
||||
|
||||
template <class Td,
|
||||
class Tg = double,
|
||||
class CTd= Vector<Td>,
|
||||
class CTg= Vector<Tg> >
|
||||
class OneDimCubicSpline: public OneDimGridFunctor<Td,Tg,CTd,CTg> {
|
||||
|
||||
public:
|
||||
|
||||
typedef OneDimGridFunctor<Td,Tg,CTd,CTg> base_type;
|
||||
typedef typename base_type::value_type value_type;
|
||||
typedef typename base_type::point_type point_type;
|
||||
typedef typename base_type::data_type data_type;
|
||||
typedef typename base_type::grid_type grid_type;
|
||||
|
||||
point_type r_min;
|
||||
point_type r_max;
|
||||
value_type first_deriv;
|
||||
value_type last_deriv;
|
||||
|
||||
OneDimCubicSpline(grid_type* gt = NULL):base_type(gt) { }
|
||||
|
||||
template<class VV>
|
||||
OneDimCubicSpline(grid_type* gt, const VV& nv):
|
||||
base_type(gt),first_deriv(0.0),last_deriv(0.0)
|
||||
{
|
||||
m_Y.resize(nv.size());
|
||||
std::copy(nv.begin(), nv.end(), m_Y.data());
|
||||
}
|
||||
|
||||
/*
|
||||
OneDimCubicSpline(grid_type* gt,
|
||||
const std::vector<Td>& nv):
|
||||
base_type(gt),first_deriv(0.0),last_deriv(0.0)
|
||||
{
|
||||
m_Y.resize(nv.size());
|
||||
std::copy(nv.begin(), nv.end(), m_Y.data());
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*@param r the radial distance
|
||||
*@param du return the derivative
|
||||
*@param d2u return the 2nd derivative
|
||||
*@return the value of the function
|
||||
*@brief Use the formula for the Cubic Spline
|
||||
*Interpolation to evaluate the function and its
|
||||
*derivatives.
|
||||
*@note Must first call the function setgrid to
|
||||
*determine the interval on the grid which contains r.
|
||||
*/
|
||||
inline value_type
|
||||
splint(point_type r, value_type& du, value_type& d2u) {
|
||||
|
||||
if(r<r_min) {
|
||||
//linear-extrapolation returns y[0]+y'*(r-r[0])
|
||||
du = first_deriv;
|
||||
d2u = 0.0;
|
||||
return m_Y[0]+first_deriv*(r-r_min);
|
||||
}
|
||||
|
||||
if(r<r_max) {
|
||||
const double onesixth = 1.0/6.0;
|
||||
//first set Loc for the grid
|
||||
int klo = m_grid->Loc;
|
||||
int khi = klo+1;
|
||||
point_type h = m_grid->dr(klo);
|
||||
point_type hinv = 1.0/h;
|
||||
point_type h6 = h*onesixth;
|
||||
point_type hh6 = h6*h;
|
||||
point_type A = (m_grid->r(khi)-r)*hinv;
|
||||
point_type dA = -hinv;
|
||||
point_type B = (r-m_grid->r(klo))*hinv;
|
||||
point_type dB = hinv;
|
||||
point_type C = A*(A*A-1.0)*hh6;
|
||||
point_type dC = -h6*(3*A*A-1.0);
|
||||
point_type D = B*(B*B-1.0)*hh6;
|
||||
point_type dD = h6*(3*B*B-1.0);
|
||||
du = dA*m_Y[klo]+dB*m_Y[khi]+ dC*m_Y2[klo] + dD*m_Y2[khi];
|
||||
d2u = A*m_Y2[klo] + B*m_Y2[khi];
|
||||
return A*m_Y[klo]+B*m_Y[khi]+C*m_Y2[klo]+D*m_Y2[khi];
|
||||
} else {
|
||||
du = 0.0; d2u = 0.0; return 1e-20;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*\param imin the index of the first valid data point
|
||||
*\param yp1 the derivative at the imin-th grid point
|
||||
*\param imax the index of the last valid data point
|
||||
*\param ypn the derivative at the imax-th grid point
|
||||
*\brief Evaluate the 2nd derivate on the grid points for
|
||||
*splint given the boundary conditions.
|
||||
*
|
||||
*In general, a grid is shared by several OneDimCubicSpline objects
|
||||
*and each object can have its own range of valid grid points.
|
||||
*r_min and r_max are used to specify the range.
|
||||
*/
|
||||
inline
|
||||
void spline(int imin, value_type yp1, int imax, value_type ypn) {
|
||||
first_deriv = yp1;
|
||||
last_deriv = ypn;
|
||||
r_min = m_grid->r(imin);
|
||||
r_max = m_grid->r(imax);
|
||||
m_Y2.resize(size());
|
||||
m_Y2 = 0.0;
|
||||
NRCubicSpline(m_grid->data()+imin, m_Y.data()+imin,
|
||||
size()-imin, yp1, ypn, m_Y2.data()+imin);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,211 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_ONEDIMGRID_BASE
|
||||
#define OHMMS_ONEDIMGRID_BASE
|
||||
|
||||
/**@file OneDimGridBase.h
|
||||
*@brief Decalaration of One-Dimesional grids
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "OhmmsPETE/OhmmsVector.h"
|
||||
|
||||
/** An abstract base class to implement a One-Dimensional grid */
|
||||
template <class T, class CT=Vector<T> >
|
||||
struct OneDimGridBase {
|
||||
|
||||
typedef T value_type;
|
||||
typedef CT Array_t;
|
||||
///the current index of the grid
|
||||
int Loc;
|
||||
///differential spacing of the grid
|
||||
T Delta;
|
||||
///array to store the radial grid data
|
||||
Array_t X;
|
||||
///assign a value
|
||||
inline T& operator[](int i) { return X[i];}
|
||||
///assign a value
|
||||
inline T& operator()(int i) { return X[i];}
|
||||
///return a value
|
||||
inline T operator[](int i) const { return X[i];}
|
||||
///return a value
|
||||
inline T operator()(int i) const { return X[i];}
|
||||
|
||||
inline const T* restrict data() const { return &(X[0]);}
|
||||
inline T* restrict data() { return &(X[0]);}
|
||||
|
||||
///return the differential spacing of the grid
|
||||
inline T dh() const { return Delta;}
|
||||
///returns \f$r(i)\f$
|
||||
inline T r(int i) const {return X[i];}
|
||||
///returns \f$r(i+1)-r(i)\f$
|
||||
inline T dr(int i) const { return X[i+1]-X[i];}
|
||||
///returns the size of the grid
|
||||
inline int size() const { return X.size();}
|
||||
///return the first grid point
|
||||
inline T rmin() const { return X[0];}
|
||||
///return the last grid point
|
||||
inline T rmax() const { return X[X.size()-1];}
|
||||
///assign and return the index for radial point r
|
||||
virtual int index(T r) = 0;
|
||||
/**
|
||||
*@param ri initial grid point
|
||||
*@param rf final grid point
|
||||
*@param n number of grid points
|
||||
*@brief Set the grid given the parameters.
|
||||
*/
|
||||
virtual void set(T ri, T rf, int n) = 0;
|
||||
};
|
||||
|
||||
/** One-Dimensional linear-grid.
|
||||
*
|
||||
* The analytic form \f[ r_i = r_0 +
|
||||
* i\left( \frac{r_f - r_0}{N-1} \right), \f]
|
||||
* where \f$ N \f$ is the number of points and the index
|
||||
* \f$ i \f$ runs from 0 to \f$ N-1 \f$
|
||||
*/
|
||||
template <class T, class CT=Vector<T> >
|
||||
struct LinearGrid: public OneDimGridBase<T,CT> {
|
||||
|
||||
// T Delta;
|
||||
T DeltaInv;
|
||||
|
||||
inline int index(T r) {
|
||||
return Loc = static_cast<int>((r-X[0])*DeltaInv);
|
||||
}
|
||||
|
||||
inline void set(T ri, T rf, int n) {
|
||||
// Delta is the differential spacing
|
||||
X.resize(n);
|
||||
Delta = (rf-ri)/static_cast<T>(n-1);
|
||||
DeltaInv = 1.0/Delta;
|
||||
X[0] = ri;
|
||||
for(int i=0; i<n-1; i++) X[i+1] = X[i]+Delta;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** One-Dimensional logarithmic-grid.
|
||||
*
|
||||
* The analytic form \f[ r_i = r_0
|
||||
* \left( \frac{r_f}{r_0} \right) ^{\frac{i}{N-1}}, \f]
|
||||
* where \f$ N \f$ is the number of points and the index
|
||||
* \f$ i \f$ runs from 0 to \f$ N-1 \f$
|
||||
*/
|
||||
template <class T, class CT=Vector<T> >
|
||||
struct LogGrid: public OneDimGridBase<T,CT> {
|
||||
|
||||
// T Delta;
|
||||
T OneOverLogDelta;
|
||||
|
||||
inline int index(T r){
|
||||
return Loc = static_cast<int>(log(r/X[0])*OneOverLogDelta);
|
||||
}
|
||||
|
||||
inline void set(T ri, T rf, int n) {
|
||||
// r(i) = ri*(rf/ri)^(i/(n-1))
|
||||
// this expression is equal to:
|
||||
// r(i) = ri*exp(dlog_ratio*i)
|
||||
// where dlog_ratio = (1/(n-1))*log(rf/ri)
|
||||
// dlog_ratio is the differential spacing
|
||||
T ratio = rf/ri;
|
||||
T log_ratio = log(ratio);
|
||||
T dlog_ratio = log_ratio/static_cast<T>(n-1);
|
||||
T expdr = exp(dlog_ratio);
|
||||
X.resize(n);
|
||||
|
||||
X[0] = ri;
|
||||
for(int i=0; i < n-1; i++) {
|
||||
X[i+1] = X[i]*expdr;
|
||||
}
|
||||
Delta = dlog_ratio;
|
||||
OneOverLogDelta = 1.0/Delta;
|
||||
}
|
||||
};
|
||||
|
||||
/**One-Dimensional logarithmic-grid starting at the
|
||||
*origin (Used in Siesta).
|
||||
*
|
||||
* The analytic form \f[ r_i = B
|
||||
* \left[ \exp(Ai)-1 \right] , \f]
|
||||
* where the number of points is \f$ N \f$ and the index
|
||||
* \f$ i \f$ runs from 0 to \f$ N-1 \f$
|
||||
*/
|
||||
template <class T, class CT=Vector<T> >
|
||||
struct LogGridZero: public OneDimGridBase<T,CT> {
|
||||
|
||||
T OneOverA;
|
||||
T OneOverB;
|
||||
|
||||
inline int index(T r){
|
||||
return Loc = static_cast<int>(log(r*OneOverB+1.0)*OneOverA);
|
||||
}
|
||||
|
||||
inline void set(T a, T b, int n) {
|
||||
OneOverA = 1.0/a;
|
||||
OneOverB = 1.0/b;
|
||||
X.resize(n);
|
||||
for(int i=0; i<n; i++)
|
||||
X[i] = b*exp(a*i)-b;
|
||||
|
||||
Delta = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
/** One-Dimensional numerical grid with arbitrary grid spacings.
|
||||
*
|
||||
* Non-Analytic grid, uses an array of values
|
||||
* (typically read in from a file).
|
||||
*/
|
||||
template <class T, class CT=Vector<T> >
|
||||
struct NumericalGrid: public OneDimGridBase<T,CT> {
|
||||
|
||||
template<class VA>
|
||||
NumericalGrid(const VA& nv) {
|
||||
// NumericalGrid(const std::vector<T>& nv) {
|
||||
X.resize(nv.size());
|
||||
std::copy(nv.begin(), nv.end(), X.data());
|
||||
}
|
||||
|
||||
int index(T r){
|
||||
int k;
|
||||
int klo=0;
|
||||
int khi=size()-1;
|
||||
while(khi-klo > 1){
|
||||
k=(khi+klo) >> 1;
|
||||
if(X[k] > r) khi=k;
|
||||
else klo=k;
|
||||
}
|
||||
return Loc = klo;
|
||||
}
|
||||
|
||||
inline void set(T ri, T rf, int n) {
|
||||
X.resize(n);
|
||||
Delta = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
ostream& operator<<(ostream& out, const OneDimGridBase<T>& rhs)
|
||||
{
|
||||
for(int i=0; i<rhs.size(); i++)
|
||||
out << i << " " << rhs.r(i) << " " << rhs.dr(i)<< endl;
|
||||
return out;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,183 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003 by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_GRID_FUNCTOR_H
|
||||
#define OHMMS_GRID_FUNCTOR_H
|
||||
|
||||
#include "Numerics/OneDimGridBase.h"
|
||||
|
||||
template<class T, unsigned D>
|
||||
struct FunctorBase { };
|
||||
|
||||
/** Implement One-Dimensional function on a radial grid.
|
||||
*\brief Store the values of the function for the
|
||||
*cooresponding grid points, \f$ y_i = y(x_i) \f$.
|
||||
*/
|
||||
|
||||
template <class Td,
|
||||
class Tg = double,
|
||||
class CTd= Vector<Td>,
|
||||
class CTg= Vector<Tg> >
|
||||
struct OneDimGridFunctor//: public FunctorBase<Td,1> {
|
||||
{
|
||||
typedef Td value_type;
|
||||
typedef Tg point_type;
|
||||
typedef CTd data_type;
|
||||
typedef OneDimGridBase<Tg,CTg> grid_type;
|
||||
typedef OneDimGridFunctor<Td,Tg,CTd,CTg> this_type;
|
||||
|
||||
/**constructor
|
||||
*@param gt the radial grid
|
||||
*/
|
||||
OneDimGridFunctor(grid_type* gt = NULL): m_grid(gt) {
|
||||
if(m_grid) resize(m_grid->size());
|
||||
}
|
||||
|
||||
///copy constructor
|
||||
OneDimGridFunctor(const this_type& a): m_grid(a.m_grid) {
|
||||
if(m_grid) resize(m_grid->size());
|
||||
}
|
||||
|
||||
///assignment operator
|
||||
const this_type& operator=(const this_type& a) {
|
||||
m_grid = a.m_grid;
|
||||
m_Y = a.m_Y;
|
||||
m_Y2 = a.m_Y2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T1>
|
||||
const this_type& operator=(const T1& x) {
|
||||
Y = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///set the number of nodes
|
||||
inline void setNumOfNodes(int n) { NumNodes = n;}
|
||||
|
||||
///return the number of nodes
|
||||
inline int getNumOfNodes() const { return NumNodes;}
|
||||
|
||||
///return the grid data
|
||||
inline value_type* data() { return &(m_Y[0]);}
|
||||
///assign the grid data
|
||||
inline const value_type* data() const { return &(m_Y[0]);}
|
||||
///return the number of data points
|
||||
inline int size() const { return m_Y.size();}
|
||||
///resize the number of data points
|
||||
inline void resize(int n) { m_Y.resize(n);}
|
||||
///return the radial grid
|
||||
inline const grid_type& grid() const { return *m_grid;}
|
||||
///assign a radial grid
|
||||
inline grid_type& grid() { return *m_grid;}
|
||||
///set the index of the grid for radius r
|
||||
inline int setgrid(point_type r) {
|
||||
return m_grid->index(r);
|
||||
}
|
||||
|
||||
/**return the differntial spacing for the grid
|
||||
*@warning only for LinearGrid and LogGrid
|
||||
*/
|
||||
inline point_type dh() const { return m_grid->dh();}
|
||||
|
||||
///return \f$r(i)\f$ the grid point at index i
|
||||
inline point_type r(int i) const { return m_grid->r(i);}
|
||||
///return \f$r(i+1)-r(i)\f$
|
||||
inline point_type dr(int i) const { return m_grid->dr(i);}
|
||||
|
||||
/**
|
||||
*@param r radial distance
|
||||
*@return the value of the function
|
||||
*@brief Evaluate the function and its derivatives, store the
|
||||
*values of the derivatives.
|
||||
*@note This should not be called frequently: only for the
|
||||
*transform function (Transform2GridFunctor)
|
||||
*/
|
||||
inline value_type f(point_type r) {
|
||||
setgrid(r);
|
||||
return splint(r,dY,d2Y);
|
||||
}
|
||||
|
||||
/**
|
||||
*@param r radial distance
|
||||
*@return the derivative of the function
|
||||
*@brief Evaluate the function and its derivatives, store the
|
||||
*values of the derivatives.
|
||||
*@note This should not be called frequently: only for the
|
||||
*transform function (Transform2GridFunctor)
|
||||
*/
|
||||
inline value_type df(point_type r) {
|
||||
setgrid(r);
|
||||
splint(r,dY,d2Y);
|
||||
return dY;
|
||||
}
|
||||
|
||||
///returns a value
|
||||
inline value_type operator()(int i) const { return m_Y[i];}
|
||||
///assign a value
|
||||
inline value_type& operator()(int i) { return m_Y[i];}
|
||||
|
||||
/**Evaluate the function and its derivatives.
|
||||
*@note Must first call the function setgrid to
|
||||
*determine the interval on the grid which contains r.
|
||||
*/
|
||||
inline value_type evaluate(point_type r, point_type rinv) {
|
||||
return Y = splint(r,dY,d2Y);
|
||||
}
|
||||
|
||||
virtual
|
||||
value_type
|
||||
splint(point_type r, value_type& du, value_type& d2u) { return 0.0; }
|
||||
|
||||
virtual void spline(int imin, value_type yp1, int imax, value_type ypn) { }
|
||||
|
||||
/**
|
||||
*@param r radial distance
|
||||
*@param rinv inverse of radial distance
|
||||
*@param du return derivative
|
||||
*@param d2u return 2nd derivative
|
||||
*@return the value of the function
|
||||
*@brief Evaluate the function and its derivatives.
|
||||
*/
|
||||
inline value_type
|
||||
evaluate(point_type r, point_type rinv, value_type& du, value_type& d2u) {
|
||||
return splint(r,du,d2u);
|
||||
}
|
||||
|
||||
///pointer to the radial grid
|
||||
grid_type* m_grid;
|
||||
|
||||
///store the value of the function
|
||||
value_type Y;
|
||||
///store the derivative of the function
|
||||
value_type dY;
|
||||
///store the second derivative of the function
|
||||
value_type d2Y;
|
||||
|
||||
///data for the function on the grid
|
||||
data_type m_Y;
|
||||
///data for the 2nd derivative on the grid
|
||||
data_type m_Y2;
|
||||
|
||||
///the number of nodes
|
||||
int NumNodes;
|
||||
};
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,209 @@
|
|||
#ifndef ONEDIMINTEGRATION_H
|
||||
#define ONEDIMINTEGRATION_H
|
||||
|
||||
/*! \fn template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2(const GF& f, GF& g)
|
||||
* \param f the integrand
|
||||
* \param g the integral of f
|
||||
* \return the numerical integral of f
|
||||
* \brief Performs the second order Runge-Kutta
|
||||
algorithm to evaluate the integral of a radial
|
||||
grid function
|
||||
\f$ f(r) \f$: \f[ g(r) = \int_a^r dr' f(r') \f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2(const GF& f, GF& g){
|
||||
|
||||
typedef typename GF::value_type value_type;
|
||||
// value_type ysum = 0.0;
|
||||
value_type yold=0.0;
|
||||
value_type ynew=0.0;
|
||||
g(0) = 0.0;
|
||||
for(int i=0; i < f.size()-1; i++){
|
||||
// ysum += 0.5*f.dr(i)*(f(i)+f(i+1));
|
||||
ynew=yold+0.5*f.dr(i)*(f(i)+f(i+1));
|
||||
// g(i+1) = ysum;
|
||||
g(i+1) = ynew;
|
||||
yold = ynew;
|
||||
}
|
||||
// return ysum;
|
||||
return yold;
|
||||
}
|
||||
|
||||
/*! \fn template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2_forward(const GF& f, GF& g)
|
||||
* \param f the integrand
|
||||
* \param g the integral of f
|
||||
* \return the numerical integral of f
|
||||
* \brief Performs the second order Runge-Kutta
|
||||
algorithm to evaluate the integral (in the
|
||||
forward direction) of a radial grid function
|
||||
\f$ f(r) \f$: \f[ g(r) = \int_a^r dr' f(r') \f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2_forward(const GF& f, GF& g){
|
||||
return integrate_RK2(f,g);
|
||||
}
|
||||
|
||||
/*! \fn template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2_backward(const GF& f, GF& g)
|
||||
* \param f the integrand
|
||||
* \param g the integral of f
|
||||
* \return the numerical integral of f
|
||||
* \brief Performs the Runge-Kutta algorithm to
|
||||
evaluate the integral (in the backwards direction)
|
||||
of a radial grid function
|
||||
\f$ f(r) \f$: \f[ g(x) = \int_x^b dx' f(x') \f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2_backward(const GF& f, GF& g){
|
||||
|
||||
// typedef typename GF::value_type value_type;
|
||||
// int last = min(f.size(),g.size())-1;
|
||||
// value_type ysum=0.0;
|
||||
// g(last) = 0.0;
|
||||
// for(int i=last; i > 0; i--){
|
||||
// ysum += 0.5*f.dr(i)*(f(i)+f(i-1));
|
||||
// g(i)=ysum;
|
||||
// }
|
||||
// return ysum;
|
||||
typedef typename GF::value_type value_type;
|
||||
int last = min(f.size(),g.size())-1;
|
||||
value_type yold = 0.0;
|
||||
value_type ynew = 0.0;
|
||||
g(last) = 0.0;
|
||||
for(int i=last; i > 0; i--){
|
||||
ynew = yold+0.5*f.dr(i-1)*(f(i)+f(i-1));
|
||||
g(i-1)=ynew;
|
||||
yold = ynew;
|
||||
}
|
||||
return yold;
|
||||
}
|
||||
|
||||
/*! \fn template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2(const GF& f)
|
||||
* \param f the integrand
|
||||
* \return the numerical integral of f
|
||||
* \brief Performs the second order Runge-Kutta
|
||||
algorithm to evaluate the integral of a radial
|
||||
grid function
|
||||
\f$ f(r) \f$: \f[ y = \int_a^b dr' f(r') \f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline
|
||||
typename GF::value_type
|
||||
integrate_RK2(const GF& f){
|
||||
|
||||
typedef typename GF::value_type value_type;
|
||||
value_type sum = 0.0;
|
||||
for(int i=0; i < f.size()-1; i++){
|
||||
sum += f.dr(i)*(f(i)+f(i+1));
|
||||
}
|
||||
return 0.5*sum;
|
||||
}
|
||||
|
||||
/*! \fn template<class GF>
|
||||
inline
|
||||
void normalize_RK2(GF& f)
|
||||
* \param f the integrand
|
||||
* \brief Normalizes the function \f$ f(r) \f$:
|
||||
\f[ f(r) = \frac{1}{\sqrt{C}} f(r) \f] where
|
||||
\f[ C = \int_a^b dr f^2(r) \f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline
|
||||
void normalize_RK2(GF& f){
|
||||
|
||||
typedef typename GF::value_type value_type;
|
||||
value_type sum = 0.0;
|
||||
for(int i=0; i < f.size()-1; i++){
|
||||
sum += f.dr(i)*(pow(f(i),2)+pow(f(i+1),2));
|
||||
}
|
||||
value_type norm = 1.0/sqrt(0.5*sum);
|
||||
for(int i=0; i < f.size(); i++) f(i) *= norm;
|
||||
}
|
||||
|
||||
template<class GT, class Fn>
|
||||
inline
|
||||
typename Fn::value_type
|
||||
integrate_RK2(const GT& grid, const Fn& a){
|
||||
|
||||
typedef typename GT::value_type value_type;
|
||||
value_type sum = 0.0;
|
||||
for(int i=0; i < f.size()-1; i++){
|
||||
sum += grid.dr(i)*(a(grid.r(i)) + a(grid.r(i+1)));
|
||||
}
|
||||
return 0.5*sum;
|
||||
}
|
||||
|
||||
template<class GF>
|
||||
typename GF::value_type
|
||||
integrate(const GF& f) {
|
||||
|
||||
typedef typename GF::value_type value_type;
|
||||
|
||||
const value_type one_third = 0.33333333333333333333333333333333;
|
||||
const value_type three_eighths = 0.375;
|
||||
const value_type BODES_FACTOR = 0.0444444444444444444444444444444;
|
||||
value_type sum = 0.0;
|
||||
|
||||
int NumIntervals = f.size() - 1;
|
||||
int rem = NumIntervals % 4;
|
||||
|
||||
///f.func(int i) return dr(i)*f(i)
|
||||
switch ( rem ) {
|
||||
case 0:
|
||||
sum += 0.0;
|
||||
break;
|
||||
case 1:
|
||||
sum += 0.5 * (f.func(0)+ f.func(1));
|
||||
break;
|
||||
case 2:
|
||||
sum += one_third * (f.func(0)+ 4.0 * f.func(1) + f.func(2));
|
||||
break;
|
||||
case 3:
|
||||
sum += three_eighths * (f.func(0)+3.0*f.func(1)
|
||||
+ 3.0*f.func(2) + f.func(3));
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = 0; i < f.size()-1; i+=4) {
|
||||
|
||||
// std::cout << i << '\n';
|
||||
int pt0=(i+0);
|
||||
int pt1=(i+1);
|
||||
int pt2=(i+2);
|
||||
int pt3=(i+3);
|
||||
int pt4=(i+4);
|
||||
|
||||
sum += 7.0 * f.func(pt0) +
|
||||
32.0 * f.func(pt1) +
|
||||
12.0 * f.func(pt2) +
|
||||
32.0 * f.func(pt3) +
|
||||
7.0 * f.func(pt4);
|
||||
}
|
||||
|
||||
return BODES_FACTOR * sum;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,151 @@
|
|||
// -*- C++ -*-
|
||||
#ifndef RADIALFUNCTIONUTILITY_H
|
||||
#define RADIALFUNCTIONUTILITY_H
|
||||
|
||||
#ifndef ONEDIMINTEGRATION_H
|
||||
#include "Numerics/OneDimIntegration.h"
|
||||
#endif
|
||||
/**@file RadialFunctorUtility.h
|
||||
@brief Utility functions for atomic Hartree-fock solutions
|
||||
@authors Jeongnim Kim, Jordan Vincent
|
||||
@note The original Prim was written in F90 by Tim Wilkens.
|
||||
*/
|
||||
|
||||
/*!\fn
|
||||
* \param g \f$Y_k(n_al_a;n_bl_b/r)\f$
|
||||
* \param a \f$psi_a\f$
|
||||
* \param b \f$\psi_b\f$
|
||||
* \param prefactor The scaling constant (simple multiplication factor)
|
||||
* \return double The result of the calculation after integration
|
||||
*
|
||||
* \brief Calculates \f$\int_0^{\infty} dr \psi_a(r) \psi_b(r)
|
||||
Y_k(n_al_a,n_bl_b/r) \psi_b(r) \f$ with appropriate scaling.
|
||||
*/
|
||||
|
||||
template<class T, class GF>
|
||||
inline T Phisq_x_Yk(const GF& g, const GF& a,
|
||||
const GF& b, T prefactor) {
|
||||
|
||||
GF t(g);
|
||||
for(int i=0; i < t.size(); i++) {
|
||||
t(i) = prefactor * g(i)*a(i)*b(i);
|
||||
}
|
||||
return integrate_RK2(t);
|
||||
}
|
||||
|
||||
|
||||
/*! \fn
|
||||
* \param g return
|
||||
* \param a \f$psi_a\f$
|
||||
* \param b \f$\psi_b\f$
|
||||
* \param k the integer parameter.
|
||||
*
|
||||
* \brief Calculates the function:
|
||||
\f[
|
||||
\frac{{\cal Y}_k(n_a l_a; n_b l_b/r)}{r}
|
||||
\f]
|
||||
*
|
||||
On Page 17 of "Quantum Theory of Atomic
|
||||
Structure" Vol 2 by JC Slater. Note: (here we use \f$ u(r) \f$ not \f$ R(r) \f$,
|
||||
where the relation is \f$ u(r) = rR(r) \f$) this function is used extensively
|
||||
to calculate the Coulomb and Exchange potentials. The actual
|
||||
equation is:
|
||||
\f[
|
||||
\frac{{\cal Y}_k(n_al_a;n_bl_b/r)}{r} =
|
||||
\frac{1}{r^{k+1}}
|
||||
\int_{0}^{r} dr' \: r'^k u_{n_a l_a}(r') u_{n_b l_b}(r')
|
||||
+ r^{k} \int_{r}^{\infty}dr' \:
|
||||
r'^{-k-1} u_{n_a l_a}(r') u_{n_b l_b}(r')
|
||||
\f]
|
||||
*/
|
||||
template<class GF>
|
||||
inline void
|
||||
Ykofr(GF& g, const GF& a, const GF& b, int k) {
|
||||
|
||||
typedef typename GF::value_type value_type;
|
||||
int n = g.size();
|
||||
|
||||
//The integrands of each of the two integrals
|
||||
GF first_integrand(g);
|
||||
GF second_integrand(g);
|
||||
|
||||
vector<value_type> r_to_k(n);
|
||||
vector<value_type> r_to_minus_k_plus_one(n);
|
||||
|
||||
//Store values for r_to_k and r_to_minus_kplus1
|
||||
for(int i=0; i < n; ++i) {
|
||||
value_type r0 = g.r(i)+1e-12;
|
||||
value_type t = pow(r0,k); // r0^k
|
||||
r_to_k[i] = t;
|
||||
r_to_minus_k_plus_one[i] = 1.0/(t*r0); // 1/r0^(k+1)
|
||||
value_type ab = a(i)*b(i);
|
||||
first_integrand(i) = r_to_k[i]*ab;
|
||||
second_integrand(i) = r_to_minus_k_plus_one[i]*ab;
|
||||
}
|
||||
|
||||
//Allow r_1 to range over all the radial grid points.
|
||||
//Store the value of the integral at each grid point in
|
||||
//temporary grid objects A and B.
|
||||
|
||||
GF A(g), B(g);
|
||||
integrate_RK2_forward(first_integrand,A);
|
||||
integrate_RK2_backward(second_integrand,B);
|
||||
|
||||
//Too many for loops here *Yk_r = r_to_minus_k_plus_one * A + r_to_k * B;
|
||||
for(int i=0; i < n; ++i) {
|
||||
g(i) = r_to_minus_k_plus_one[i]*A(i)+r_to_k[i]*B(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \fn
|
||||
* \param g the grid function to be returned
|
||||
* \param y the grid function to be transformed
|
||||
* \param a \f$\psi_a\f$
|
||||
* \param b \f$\psi_b\f$
|
||||
* \param coeff a coefficient
|
||||
*
|
||||
* \brief Makes \f$V_{Exchange}\f$ a local function.
|
||||
*
|
||||
\f$ V_{Exchange} \f$ is a non-local operator:
|
||||
\f[
|
||||
\hat{V}_{Exchange} \psi_a(r) = -\sum_b
|
||||
\delta_{\sigma_a,\sigma_b}\int dr'
|
||||
\frac{\psi_b^*(r')\psi_a(r')}{|r-r'|}\psi_b(r),
|
||||
\f]
|
||||
It is possible to transform this into a local operator by multiplying
|
||||
and dividing by $\psi_a(r)$:
|
||||
\f[
|
||||
-\sum_b \delta_{\sigma_a,\sigma_b}\int dr'
|
||||
\frac{\psi_b^* (r')\psi_a(r')\psi_b(r')\psi_b(r)}{\psi_a(r)|r-r'|} \psi_a(r)
|
||||
\f]
|
||||
*/
|
||||
|
||||
template<class GF>
|
||||
inline void
|
||||
Make_Loc_Pot(GF& g, const GF& y, const GF& a, const GF& b,
|
||||
typename GF::value_type coeff) {
|
||||
|
||||
int max_pt, pt=1;
|
||||
typename GF::value_type ratio;
|
||||
while(a(pt)/a(pt-1) >= 1.0 && pt<a.size()-1) {
|
||||
pt++;
|
||||
}
|
||||
max_pt = pt;
|
||||
const double tol = pow(10.0,-10.0);
|
||||
for(pt=0; pt < g.size(); pt++) {
|
||||
if(fabs(a(pt)) > tol){
|
||||
ratio = b(pt)/a(pt);
|
||||
if(pt >= max_pt && fabs(ratio) > 1000) {ratio = 1000000.0 / ratio;}
|
||||
g(pt) -= coeff*ratio*y(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//}
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
// (c) Copyright 2003- by Jeongnim Kim
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Jeongnim Kim
|
||||
// National Center for Supercomputing Applications &
|
||||
// Materials Computation Center
|
||||
// University of Illinois, Urbana-Champaign
|
||||
// Urbana, IL 61801
|
||||
// e-mail: jnkim@ncsa.uiuc.edu
|
||||
// Tel: 217-244-6319 (NCSA) 217-333-3324 (MCC)
|
||||
//
|
||||
// Supported by
|
||||
// National Center for Supercomputing Applications, UIUC
|
||||
// Materials Computation Center, UIUC
|
||||
// Department of Physics, Ohio State University
|
||||
// Ohio Supercomputer Center
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// -*- C++ -*-
|
||||
#ifndef OHMMS_SLATERTYPEORBITAL_H
|
||||
#define OHMMS_SLATERTYPEORBITAL_H
|
||||
#include <math.h>
|
||||
|
||||
/**class for Slater-type orbitals
|
||||
*@f[
|
||||
*\Psi_{n,l,m}({\bf R}) = N r^{n-1} \exp{-Zr} Y_{lm}(\theta,\phi)
|
||||
*@f]
|
||||
*/
|
||||
template<class T>
|
||||
struct RadialSTO {
|
||||
typedef T value_type;
|
||||
int NminusOne;
|
||||
T Z;
|
||||
T Norm;
|
||||
T Y, dY, d2Y;
|
||||
RadialSTO(): NminusOne(0), Z(1.0), Norm(1.0) { }
|
||||
RadialSTO(int n, double z, double norm=1.0):
|
||||
NminusOne(n-1), Z(z),Norm(norm) { }
|
||||
|
||||
inline void setgrid(T r) { }
|
||||
|
||||
inline T f(T r) const {
|
||||
return pow(r,NminusOne)*exp(-Z*r)*Norm;
|
||||
}
|
||||
|
||||
inline T df(T r) const {
|
||||
T rnl = pow(r,NminusOne)*exp(-Z*r)*Norm;
|
||||
return (NminusOne/r-Z)*rnl;
|
||||
}
|
||||
|
||||
inline void evaluate(T r, T rinv) {
|
||||
Y = evaluate(r,rinv,dY,d2Y);
|
||||
}
|
||||
|
||||
inline T evaluate(T r, T rinv, T& drnl, T& d2rnl) {
|
||||
T rnl = pow(r,NminusOne)*exp(-Z*r)*Norm;
|
||||
T x = NminusOne*rinv-Z;
|
||||
drnl = rnl*x;
|
||||
d2rnl = rnl*(x*x-NminusOne*rinv*rinv);
|
||||
return rnl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Generic Slater-Type Orbital
|
||||
*
|
||||
*The analytic form
|
||||
\f[
|
||||
\chi_{n,\xi}(r) = N r^{n-1} \exp{-\xi r}
|
||||
\f]
|
||||
*
|
||||
*@note For QMC we are interested in
|
||||
\f[
|
||||
\frac{\chi_{n,\xi}(r)}{r^l} = N r^{n-l-1} \exp{-\xi r}
|
||||
/f]
|
||||
*/
|
||||
template<class T>
|
||||
struct GenericSTO {
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
int ID;
|
||||
int N;
|
||||
T Z;
|
||||
T Norm;
|
||||
T Y, dY, d2Y;
|
||||
|
||||
GenericSTO(): N(-1), Z(1.0), Norm(1.0) { }
|
||||
GenericSTO(int n, double z, double norm=1.0): N(n), Z(z),Norm(norm) { }
|
||||
|
||||
inline void setgrid(T r) { }
|
||||
|
||||
inline T f(T r) const {
|
||||
return exp(-Z*r)*Norm*pow(r,N);
|
||||
}
|
||||
|
||||
inline T df(T r) const {
|
||||
T rnl = exp(-Z*r)*Norm;
|
||||
if(N == 0) {
|
||||
return -Z*rnl;
|
||||
} else {
|
||||
return rnl*pow(r,N)*(N/r-Z);
|
||||
}
|
||||
}
|
||||
|
||||
inline void evaluate(T r, T rinv) {
|
||||
Y = evaluate(r,rinv,dY,d2Y);
|
||||
}
|
||||
inline T evaluate(T r, T rinv, T& drnl, T& d2rnl) {
|
||||
T rnl = exp(-Z*r)*Norm;
|
||||
if(N == 0) {
|
||||
drnl = -Z*rnl;
|
||||
d2rnl = rnl*Z*Z;
|
||||
} else {
|
||||
rnl *= pow(r,N);
|
||||
T x = N*rinv-Z;
|
||||
drnl = rnl*x;
|
||||
d2rnl = rnl*(x*x-N*rinv*rinv);
|
||||
}
|
||||
return rnl;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct STONorm {
|
||||
|
||||
std::vector<T> Factorial;
|
||||
|
||||
explicit STONorm(int nmax=1) {
|
||||
set(nmax);
|
||||
}
|
||||
|
||||
void set(int nmax) {
|
||||
int n = 2*nmax+2;
|
||||
Factorial.resize(n+1);
|
||||
Factorial[0] = 1.0;
|
||||
for (int i=1;i<n+1;i++) Factorial[i] = Factorial[i-1]*static_cast<T>(i);
|
||||
}
|
||||
|
||||
inline T operator()(int n, T screen) {
|
||||
return
|
||||
1.0/sqrt(Factorial[2*n+2]*4.0*(4.0*atan(1.0))/pow(2.0*screen,2*n+3));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* $RCSfile$ $Author$
|
||||
* $Revision$ $Date$
|
||||
* $Id$
|
||||
***************************************************************************/
|
|
@ -0,0 +1,217 @@
|
|||
#ifndef __SphericalTensor_h_
|
||||
#define __SphericalTensor_h_
|
||||
|
||||
//#include <valarray>
|
||||
//#include "Point.h"
|
||||
|
||||
/**Class SphericalTensor
|
||||
* @author John Shumway
|
||||
* @author Jeongnim Kim
|
||||
* \brief evaluates the Real Spherical Harmonics
|
||||
\f[
|
||||
r^l \Re (Y_l^m(\theta,\phi)).
|
||||
\f]
|
||||
*
|
||||
A list of the real spherical harmonics for the \textit{s},
|
||||
\textit{p} and \textit{d} states
|
||||
\f[ \Re (Y_0^0) = \sqrt{\frac{1}{4\pi}} = s \f]
|
||||
\f[ r\Re (Y_1^{-1}) = -\sqrt{\frac{3}{8\pi}}y = p_y \f]
|
||||
\f[ r\Re (Y_1^0) = \sqrt{\frac{3}{4\pi}}z = p_z \f]
|
||||
\f[ r\Re (Y_1^1) = -\sqrt{\frac{3}{8\pi}}x = p_x \f]
|
||||
\f[ r^2\Re (Y_2^{-2}) = \sqrt{\frac{15}{8\pi}}xy = d_{xy} \f]
|
||||
\f[ r^2\Re (Y_2^{-1}) = -\sqrt{\frac{15}{8\pi}}yz = d_{yz} \f]
|
||||
\f[ r^2\Re (Y_2^0) = \sqrt{\frac{5}{16\pi}}(3z^2-r^2) = d_{z^2} \f]
|
||||
\f[ r^2\Re (Y_2^1) = -\sqrt{\frac{15}{8\pi}}xz = d_{xz} \f]
|
||||
\f[ r^2\Re (Y_2^2) = \sqrt{\frac{15}{32\pi}}(x^2-y^2) = d_{x^2-y^2} \f]
|
||||
*
|
||||
The template parameter T is the value_type, e.g. double, and the
|
||||
template parameter Point_t is a vector type which must have the
|
||||
operator[] defined.
|
||||
*/
|
||||
|
||||
template<class T, class Point_t>
|
||||
class SphericalTensor {
|
||||
public :
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
///constructor
|
||||
explicit SphericalTensor(const int lmax);
|
||||
|
||||
///makes a table of \f$ r^{l} \Re (Y_l^m) \f$ and their gradients up to lmax.
|
||||
void evaluate(const Point_t& p);
|
||||
|
||||
///returns the index \f$ l(l+1)+m \f$
|
||||
inline int index(int l, int m) const {return (l*(l+1))+m;}
|
||||
|
||||
///returns the value of \f$ r^{l} \Re (Y_l^m) \f$ given l,m
|
||||
inline value_type getYlm(int l, int m) const
|
||||
{return Ylm[index(l,m)];}
|
||||
|
||||
///returns the gradient of \f$ r^{l} \Re (Y_l^m) \f$ given l,m
|
||||
inline Point_t getGradYlm(int l, int m) const
|
||||
{return gradYlm[index(l,m)];}
|
||||
|
||||
///returns the value of \f$ r^{l} \Re (Y_l^m) \f$ given index lm
|
||||
inline value_type getYlm(int lm) const {return Ylm[lm];}
|
||||
|
||||
///returns the gradient of \f$ r^{l} \Re (Y_l^m) \f$ given index lm
|
||||
inline Point_t getGradYlm(int lm) const {return gradYlm[lm];}
|
||||
|
||||
inline int size() const { return Ylm.size();}
|
||||
|
||||
inline int lmax() const { return Lmax;}
|
||||
|
||||
private :
|
||||
|
||||
int Lmax;
|
||||
vector<value_type> Ylm;
|
||||
vector<Point_t> gradYlm;
|
||||
};
|
||||
|
||||
template<class T, class Point_t>
|
||||
SphericalTensor<T, Point_t>::SphericalTensor(const int lmax) : Lmax(lmax){
|
||||
Ylm.resize((lmax+1)*(lmax+1));
|
||||
gradYlm.resize((lmax+1)*(lmax+1));
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Point_t>
|
||||
void SphericalTensor<T,Point_t>::evaluate(const Point_t& p) {
|
||||
|
||||
value_type x=p[0], y=p[1], z=p[2];
|
||||
|
||||
const value_type pi = 4.0*atan(1.0);
|
||||
const value_type pi4 = 4.0*pi;
|
||||
|
||||
/* Calculate r, cos(theta), sin(theta), cos(phi), sin(phi) from input
|
||||
coordinates. Check here the coordinate singularity at cos(theta) = +-1.
|
||||
This also takes care of r=0 case. */
|
||||
|
||||
value_type cphi,sphi,ctheta;
|
||||
value_type r2xy=x*x+y*y;
|
||||
value_type r=sqrt(r2xy+z*z);
|
||||
if (r2xy == 0.0) {
|
||||
cphi = 0.0;
|
||||
sphi = 1.0;
|
||||
ctheta = (z<0)?-1.0:1.0;
|
||||
} else {
|
||||
ctheta = z/r;
|
||||
value_type rxyi = 1.0/sqrt(r2xy);
|
||||
cphi = x*rxyi;
|
||||
sphi = y*rxyi;
|
||||
}
|
||||
|
||||
value_type stheta = sqrt(1.0-ctheta*ctheta);
|
||||
|
||||
/* Now to calculate the associated legendre functions P_lm from the
|
||||
recursion relation from l=0 to lmax. Conventions of J.D. Jackson,
|
||||
Classical Electrodynamics are used. */
|
||||
|
||||
Ylm[0] = 1.0;
|
||||
|
||||
// calculate P_ll and P_l,l-1
|
||||
|
||||
value_type fac = 1.0;
|
||||
int j = -1;
|
||||
for (int l=1; l<=Lmax; l++) {
|
||||
j += 2;
|
||||
fac *= -j*stheta;
|
||||
int ll=index(l,l);
|
||||
int l1=index(l,l-1);
|
||||
int l2=index(l-1,l-1);
|
||||
Ylm[ll] = fac;
|
||||
Ylm[l1] = j*ctheta*Ylm[l2];
|
||||
}
|
||||
|
||||
// Use recurence to get other plm's //
|
||||
|
||||
for (int m=0; m<Lmax-1; m++) {
|
||||
int j = 2*m+1;
|
||||
for (int l=m+2; l<=Lmax; l++) {
|
||||
j += 2;
|
||||
int lm=index(l,m);
|
||||
int l1=index(l-1,m);
|
||||
int l2=index(l-2,m);
|
||||
Ylm[lm] = (ctheta*j*Ylm[l1]-(l+m-1)*Ylm[l2])/(l-m);
|
||||
}
|
||||
}
|
||||
|
||||
// Now to calculate r^l Y_lm. //
|
||||
|
||||
value_type sphim,cphim,fac2,temp;
|
||||
Ylm[0] = 1.0/sqrt(pi4);
|
||||
value_type rpow = 1.0;
|
||||
for (int l=1; l<=Lmax; l++) {
|
||||
rpow *= r;
|
||||
fac = rpow*sqrt((2*l+1)/pi4);
|
||||
int l0=index(l,0);
|
||||
Ylm[l0] *= fac;
|
||||
cphim = 1.0;
|
||||
sphim = 0.0;
|
||||
for (int m=1; m<=l; m++) {
|
||||
fac2 = (l+m)*(l+1-m);
|
||||
fac = fac/sqrt(fac2);
|
||||
temp = cphim*cphi-sphim*sphi;
|
||||
sphim = sphim*cphi+cphim*sphi;
|
||||
cphim = temp;
|
||||
int lm = index(l,m);
|
||||
temp = fac*Ylm[lm];
|
||||
Ylm[lm] = temp*cphim;
|
||||
lm = index(l,-m);
|
||||
Ylm[lm] = temp*sphim;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculating Gradient now//
|
||||
|
||||
for (int l=0; l<Lmax+1; l++) {
|
||||
for (int m=-l; m<l+1; m++) {
|
||||
int lm = index(l-1,0);
|
||||
value_type fac = ((value_type) (2*l+1))/(2*l-1);
|
||||
value_type gx,gy,gz,dpr,dpi,dmr,dmi;
|
||||
int ma = abs(m);
|
||||
value_type cp = sqrt(fac*(l-ma-1)*(l-ma));
|
||||
value_type cm = sqrt(fac*(l+ma-1)*(l+ma));
|
||||
value_type c0 = sqrt(fac*(l-ma)*(l+ma));
|
||||
gz = (l > ma) ? c0*Ylm[lm+m]:0.0;
|
||||
if (l > ma+1) {
|
||||
dpr = cp*Ylm[lm+ma+1];
|
||||
dpi = cp*Ylm[lm-ma-1];
|
||||
} else {
|
||||
dpr = 0.0;
|
||||
dpi = 0.0;
|
||||
}
|
||||
if (l > 1) {
|
||||
switch (ma) {
|
||||
|
||||
case 0:
|
||||
dmr = -cm*Ylm[lm+1];
|
||||
dmi = cm*Ylm[lm-1];
|
||||
break;
|
||||
case 1:
|
||||
dmr = cm*Ylm[lm];
|
||||
dmi = 0.0;
|
||||
break;
|
||||
default:
|
||||
dmr = cm*Ylm[lm+ma-1];
|
||||
dmi = cm*Ylm[lm-ma+1];
|
||||
}
|
||||
} else {
|
||||
dmr = (l==1) ? cm*Ylm[lm]:0.0;
|
||||
dmi = 0.0;
|
||||
}
|
||||
if (m < 0) {
|
||||
gx = 0.5*(dpi-dmi);
|
||||
gy = -0.5*(dpr+dmr);
|
||||
} else {
|
||||
gx = 0.5*(dpr-dmr);
|
||||
gy = 0.5*(dpi+dmi);
|
||||
}
|
||||
lm = index(l,m);
|
||||
gradYlm[lm] = Point_t(gx,gy,gz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef GUARD_SPLINE3DCONFIGURATION_H
|
||||
#define GUARD_SPLINE3DCONFIGURATION_H
|
||||
|
||||
#include "OhmmsPETE/TinyVector.h"
|
||||
#include "OhmmsPETE/OhmmsVector.h"
|
||||
|
||||
typedef TinyVector<int,3> gridvec_t;
|
||||
typedef TinyVector<double,3> posvec_t;
|
||||
typedef Vector<double> scalar_array_t;
|
||||
typedef Vector<posvec_t> posarray_t;
|
||||
typedef vector<posvec_t> rarray_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,126 @@
|
|||
#include "Numerics/Spline3D/CubicSpline.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void CubicSpline::Update(){
|
||||
|
||||
blitz::Array<double,1> mu(n_x);
|
||||
|
||||
F(0)[1] = 1.5 * ( F(1)[0] - F(0)[0] ) * invh;
|
||||
F(n_x-1)[1] = 1.5 * ( F(n_x-1)[0] - F(n_x-2)[0] ) * invh;
|
||||
mu(0) = 0.5;
|
||||
|
||||
for(int i = 1; i < n_x-1; i++){
|
||||
double lambda = 0.25;
|
||||
mu(i) = 0.5 - lambda;
|
||||
F(i)[1] = 3.0* invh * ( lambda * ( F(i)[0] - F(i-1)[0] ) +
|
||||
mu(i) * ( F(i+1)[0] - F(i)[0] ) );
|
||||
double ci = 1.0 - lambda * mu(i-1);
|
||||
F(i)[1] -= lambda * F(i-1)[1];
|
||||
mu(i) /= ci;
|
||||
F(i)[1] /= ci;
|
||||
}
|
||||
|
||||
int i = n_x - 1;
|
||||
double lambda = 0.5;
|
||||
mu(i) = 0.5 - lambda;
|
||||
F(i)[1] = 3.0 * invh * lambda * ( F(i)[0] - F(i-1)[0] );
|
||||
double ci = 1.0 - lambda * mu(i-1);
|
||||
F(i)[1] -= lambda * F(i-1)[1];
|
||||
mu(i) /= ci;
|
||||
F(i)[1] /= ci;
|
||||
|
||||
for( i = n_x - 2; i >= 0; i-- )
|
||||
F(i)[1] -= mu(i) * F(i+1)[1];
|
||||
|
||||
for(int j = 0; j < n_x; j++)
|
||||
cout << F(j)[0] << '\t' << F(j)[1] << endl;
|
||||
exit(-1);
|
||||
|
||||
UpToDate = true;
|
||||
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void CubicSpline::Update(double dfi, double dff){
|
||||
|
||||
blitz::Array<double,1> mu(n_x);
|
||||
|
||||
F(0)[1] = dfi;
|
||||
F(n_x-1)[1] = dff;
|
||||
mu(0) = 0.5;
|
||||
|
||||
for(int i = 1; i < n_x-1; i++){
|
||||
double lambda = 0.25;
|
||||
mu(i) = 0.5 - lambda;
|
||||
F(i)[1] = 3.0* invh * ( lambda * ( F(i)[0] - F(i-1)[0] ) +
|
||||
mu(i) * ( F(i+1)[0] - F(i)[0] ) );
|
||||
double ci = 1.0 - lambda * mu(i-1);
|
||||
F(i)[1] -= lambda * F(i-1)[1];
|
||||
mu(i) /= ci;
|
||||
F(i)[1] /= ci;
|
||||
}
|
||||
|
||||
for( int i = n_x - 2; i > 0; i-- )
|
||||
F(i)[1] -= mu(i) * F(i+1)[1];
|
||||
|
||||
UpToDate = true;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void CubicSpline::Update(){
|
||||
|
||||
blitz::Array<double,1> a(n_x),b(n_x),c(n_x),r(n_x);
|
||||
|
||||
/// initilaise the coefficient matrix
|
||||
a(0) = 0.0; b(0) = 2.0; b(n_x-1) = 2; c(n_x-1) = 0.0;
|
||||
for(int i = 1; i < n_x-1; i++){
|
||||
a(i) = 1.0; b(i) = 4.0; c(i) = 1.0;
|
||||
}
|
||||
|
||||
/// initialise the right hand side
|
||||
double fac = 3* invh ;
|
||||
r(0) = fac*(F(1)[0] - F(0)[0]) - 0.5*d2i;
|
||||
for(int i = 1; i < n_x-1; i++) r(i) = fac*(F(i+1)[0]-F(i-1)[0]);
|
||||
r(n_x-1) = fac*(F(n_x-1)[0] - F(n_x-2)[0]) + 0.5*d2f;
|
||||
|
||||
|
||||
blitz::Array<double,1> gamma(n_x);
|
||||
|
||||
/// decomposition and forward substitution
|
||||
double beta=b(0);
|
||||
F(0)[1] = r(0)/beta;
|
||||
for(int j = 1; j < n_x; j++){
|
||||
gamma(j) = c(j-1)/beta;
|
||||
beta = b(j) - a(j)*gamma(j);
|
||||
F(j)[1] = (r(j)-a(j)*F(j-1)[1])/beta;
|
||||
}
|
||||
/// backsubstitution
|
||||
for(int j = n_x-2; j >= 0; j--)
|
||||
F(j)[1] -= gamma(j+1)*F(j+1)[1];
|
||||
|
||||
|
||||
// for(int i = 0; i < n_x-1; i++)
|
||||
// cout << F(i)[0] << '\t' << F(i)[1] << endl;
|
||||
// exit(-1);
|
||||
|
||||
UpToDate = true;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
*/
|
|
@ -0,0 +1,143 @@
|
|||
#ifndef GUARD_CUBICSPLINE_H
|
||||
#define GUARD_CUBICSPLINE_H
|
||||
|
||||
#include "Numerics/Spline3D/Config.h"
|
||||
#include "Numerics/Spline3D/uGrid1D.h"
|
||||
#include "Numerics/Spline3D/SetSplinePoint.h"
|
||||
#include <fstream>
|
||||
#include <blitz/array.h>
|
||||
|
||||
/// This is Cubic Splines with natural boundary conditions, i.e.
|
||||
/// the second derivative vanishes at the boundary, not suitable for
|
||||
/// functions like sines and cosines.
|
||||
|
||||
/// Each point of F contains:
|
||||
/// 0) F(x,y,z)
|
||||
/// 1) dF/dx
|
||||
|
||||
class CubicSpline{
|
||||
|
||||
/// functions which depend on the point where the interpolated value
|
||||
/// is required. t = (x - xi)/h
|
||||
inline double p1(double t)
|
||||
{ return ((t-1.0)*(t-1.0)*(1.0+2.0*t)); }
|
||||
inline double p2(double t)
|
||||
{ return (t*t*(3.0-2.0*t)); }
|
||||
inline double q1(double t)
|
||||
{ return (t*(t-1.0)*(t-1.0)); }
|
||||
inline double q2(double t)
|
||||
{ return (t*t*(t-1.0)); }
|
||||
inline double dp1(double t)
|
||||
{ return (6.0*t*(t-1.0)); }
|
||||
inline double dq1(double t)
|
||||
{ return ((t-1.0)*(3.0*t-1.0)); }
|
||||
inline double dp2(double t)
|
||||
{ return (-dp1(t)); }
|
||||
inline double dq2 (double t)
|
||||
{ return ((3.0*t - 2.0)*t); }
|
||||
inline double d2p1(double t)
|
||||
{ return (12.0*t-6.0); }
|
||||
inline double d2q1 (double t)
|
||||
{ return (6.0*t - 4.0); }
|
||||
inline double d2p2 (double t)
|
||||
{ return (-d2p1(t)); }
|
||||
inline double d2q2 (double t)
|
||||
{ return (6.0*t - 2.0); }
|
||||
|
||||
// dim: Dimension to calculate derivative w.r.t
|
||||
// source: Function to differentiate
|
||||
// dest: where to put result
|
||||
void UpdateX (int source, int dest);
|
||||
|
||||
/// whether the first derivatives have been calculated using the
|
||||
/// m-relations.
|
||||
bool UpToDate;
|
||||
|
||||
|
||||
|
||||
int n_x;
|
||||
double d2i;
|
||||
double d2f;
|
||||
double h;
|
||||
double invh;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef double value_type;
|
||||
|
||||
/// function and derivatives at each point
|
||||
blitz::Array<blitz::TinyVector<double,2>,1> F;
|
||||
|
||||
uGrid1D* m_grid;
|
||||
|
||||
/// constructor
|
||||
CubicSpline(uGrid1D* agrid){
|
||||
|
||||
m_grid = agrid;
|
||||
|
||||
n_x = agrid->m_size;
|
||||
h = agrid->m_h;
|
||||
invh = 1.0/h;
|
||||
|
||||
d2i = 0.0;
|
||||
d2f = 0.0;
|
||||
|
||||
F.resize(n_x);
|
||||
UpToDate = false;
|
||||
|
||||
}
|
||||
|
||||
inline void set_bc(double ad2i, double ad2f){
|
||||
d2i = ad2i;
|
||||
d2f = ad2f;
|
||||
return;
|
||||
}
|
||||
|
||||
inline double operator()(int ix) const
|
||||
{
|
||||
return (F(ix)[0]);
|
||||
}
|
||||
|
||||
inline double& operator()(int ix)
|
||||
{
|
||||
UpToDate = false;
|
||||
return (F(ix)[0]);
|
||||
}
|
||||
|
||||
/// update the derivatives using the m-relations
|
||||
void Update();
|
||||
void Update(double,double);
|
||||
|
||||
inline double evaluate(const double x,
|
||||
double& gradf,
|
||||
double& lapf){
|
||||
|
||||
double val;
|
||||
|
||||
//if( !UpToDate ) Update(); /// m-relations
|
||||
|
||||
int ix = m_grid->xl(x); /// get the lowest grid-point
|
||||
|
||||
double u = (x-m_grid->m_coord[ix])*invh;
|
||||
|
||||
double& Y00 = F(ix)[0];
|
||||
double& Y01 = F(ix)[1];
|
||||
double& Y10 = F(ix+1)[0];
|
||||
double& Y11 = F(ix+1)[1];
|
||||
|
||||
val = Y00 * p1(u) + Y10 * p2(u) + h* ( Y01 * q1(u) + Y11 * q2(u) );
|
||||
|
||||
gradf = invh * ( Y00 * dp1(u) + Y10 * dp2(u) )
|
||||
+ Y01 * dq1(u) + Y11 * dq2(u) ;
|
||||
|
||||
lapf = invh * ( invh * ( Y00 * d2p1(u) + Y10 * d2p2(u) )
|
||||
+ Y01 * d2q1(u) + Y11 * d2q2(u) );
|
||||
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,102 @@
|
|||
#include "Numerics/Spline3D/Grid1D.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void Grid1D::init(int nsections,
|
||||
int npts,
|
||||
double xi,
|
||||
const vector<int>& nrho,
|
||||
const vector<double>& dh){
|
||||
|
||||
m_size = npts;
|
||||
m_coord.resize(m_size);
|
||||
m_sections = nsections;
|
||||
m_start = xi;
|
||||
|
||||
/// assign and initialise arrays
|
||||
m_h.resize(m_size); m_M.resize(m_size+1); m_M[0] = 0;
|
||||
for(int isec = 0; isec < m_sections; isec++){
|
||||
m_h[isec] = dh[isec];
|
||||
m_M[isec+1] = m_M[isec] + nrho[isec];
|
||||
}
|
||||
|
||||
/// compute the coordinates
|
||||
int ipt = 0; m_coord[0] = m_start;
|
||||
for(int isec = 0; isec < m_size; isec++){
|
||||
for(int ix = m_M[isec]; ix < m_M[isec+1]; ix++){
|
||||
ipt++; m_coord[ipt] = m_coord[ipt-1] + m_h[isec];
|
||||
}
|
||||
}
|
||||
|
||||
m_end = m_coord[m_size-1];
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void Grid1D::init(int xi,
|
||||
int xf,
|
||||
const Grid1D& agrid){
|
||||
|
||||
m_size = xf - xi + 1;
|
||||
m_coord.resize(m_size);
|
||||
|
||||
int si, sf; /// the indices of the initial and final sections
|
||||
bool flag1 = true, flag2 = true;
|
||||
for(int isec = 0; isec < agrid.m_sections; isec++){
|
||||
if(flag1 && xi <= agrid.m_M[isec+1]) { si = isec; flag1 = false; }
|
||||
if(flag2 && xf <= agrid.m_M[isec+1]) { sf = isec; flag2 = false; }
|
||||
}
|
||||
m_sections = sf - si + 1;
|
||||
|
||||
/// assign arrays
|
||||
m_M.resize(m_size+1); m_h.resize(m_size); m_M[0] = 0;
|
||||
for(int isec = 1; isec < m_sections; isec++)
|
||||
m_M[isec] = agrid.m_M[isec+si] - xi;
|
||||
m_M[m_sections] = xf - xi;
|
||||
|
||||
/// the grid spacings
|
||||
for(int isec = 0; isec < m_sections; isec++)
|
||||
m_h[isec] = agrid.m_h[si+isec];
|
||||
|
||||
/// compute the coordinates
|
||||
int ipt = 0; m_coord[0] = agrid.m_coord[xi];
|
||||
for(int isec = 0; isec < m_size; isec++){
|
||||
for(int ix = m_M[isec]; ix < m_M[isec+1]; ix++){
|
||||
ipt++; m_coord[ipt] = m_coord[ipt-1] + m_h[isec];
|
||||
}
|
||||
}
|
||||
|
||||
m_start = m_coord[0]; m_end = m_coord[m_size-1];
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
int Grid1D::xl(double x){
|
||||
|
||||
/// the start and end points
|
||||
int a = 0; int b = m_size-1;
|
||||
|
||||
while( b - a > 1 ){
|
||||
int m = a + ( b - a )/2 ; // divide by 2^{1}
|
||||
if( x >= m_coord[m] ){
|
||||
a = m;
|
||||
} else {
|
||||
b = m;
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
|
||||
}
|
||||
|
||||
int Grid1D::xn(double x){
|
||||
|
||||
int i = xl(x); /// get the lowest Grid point
|
||||
if( x - m_coord[i] > 0.5*h(i) ) i += 1;
|
||||
return i;
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef GUARD_GRID1D_H
|
||||
#define GUARD_GRID1D_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Grid1D{
|
||||
|
||||
public:
|
||||
|
||||
/// number of different Grid density sections (regions)
|
||||
int m_sections;
|
||||
|
||||
/// total number of Grid points : 0 to m_size - 1
|
||||
int m_size;
|
||||
|
||||
/// coordinate of first and last grid points
|
||||
double m_start;
|
||||
double m_end;
|
||||
|
||||
/// coordinates
|
||||
std::vector<double> m_coord;
|
||||
|
||||
/// the interval points
|
||||
std::vector<int> m_M;
|
||||
|
||||
/// Grid widths
|
||||
std::vector<double> m_h;
|
||||
|
||||
/// Constructor
|
||||
Grid1D(){}
|
||||
|
||||
/// initialise with the entire data from input
|
||||
void init(int, int, double, const std::vector<int>&,
|
||||
const std::vector<double>&);
|
||||
|
||||
/// initialise from part of a supplied Grid
|
||||
void init(int, int, const Grid1D&);
|
||||
|
||||
|
||||
/// the lowest Grid-point for coordinate x
|
||||
int xl(double);
|
||||
|
||||
/// the nearest Grid-point for coordinate x
|
||||
int xn(double);
|
||||
|
||||
/// the Grid width for coordinate x
|
||||
inline double h(double x){ return h(xl(x)); }
|
||||
|
||||
/// the Grid width for some Grid point i
|
||||
inline double h(int i) { return m_coord[i+1] - m_coord[i];}
|
||||
|
||||
/// the size of the Grid :
|
||||
inline int Size() { return m_size; }
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,220 @@
|
|||
#ifndef GUARD_GRID3D_H
|
||||
#define GUARD_GRID3D_H
|
||||
|
||||
#include <vector>
|
||||
#include "Numerics/Spline3D/Config.h"
|
||||
#include "Numerics/Spline3D/Grid1D.h"
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
class Grid3D{
|
||||
|
||||
public:
|
||||
|
||||
/// number of points along each direction
|
||||
int n_x, n_y, n_z;
|
||||
|
||||
/// total number of points in the Grid3D : 0 to m_size-1
|
||||
int m_size;
|
||||
|
||||
/// array of the axes Grid1D
|
||||
std::vector<Grid1D> m_axis;
|
||||
|
||||
/// Constructor :: create the three axes
|
||||
Grid3D(){ m_axis.resize(3); }
|
||||
|
||||
/// initialise an axis with entire data from the input
|
||||
void init(int idir,
|
||||
int nsections,
|
||||
int npts,
|
||||
double xi,
|
||||
const std::vector<int>& nrho,
|
||||
const std::vector<double>& dh){
|
||||
|
||||
m_axis[idir].init(nsections,npts,xi,nrho,dh);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// initialise the Grid3D from another Grid3D
|
||||
void init(const gridvec_t& ri,
|
||||
const gridvec_t& rf,
|
||||
const Grid3D* agrid){
|
||||
|
||||
for(int idir = 0; idir < 3; idir++)
|
||||
m_axis[idir].init(ri[idir],rf[idir],agrid->m_axis[idir]);
|
||||
|
||||
set_size();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void set_size(){
|
||||
|
||||
n_x = m_axis[0].Size();
|
||||
n_y = m_axis[1].Size();
|
||||
n_z = m_axis[2].Size();
|
||||
|
||||
m_size = n_x * n_y * n_z;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// index of a Grid3D point
|
||||
inline int index(const gridvec_t& ir){
|
||||
return ir[0] + n_x * ( ir[1] + n_y * ir[2] );
|
||||
}
|
||||
|
||||
/// index of a Grid3D point
|
||||
inline int index(int ix, int iy, int iz){
|
||||
return ix + n_x * ( iy + n_y * iz );
|
||||
}
|
||||
|
||||
/// Grid3D point corresponding to index
|
||||
inline gridvec_t ipt(int index){
|
||||
|
||||
gridvec_t ir;
|
||||
int nxy = n_x * n_y;
|
||||
ir[2] = index/nxy; index -= nxy*ir[2];
|
||||
ir[1] = index/n_x; index -= n_x*ir[1];
|
||||
ir[0] = index;
|
||||
|
||||
return ir;
|
||||
|
||||
}
|
||||
|
||||
/// lowest Grid3D point
|
||||
inline gridvec_t ptl(const posvec_t& r){
|
||||
|
||||
gridvec_t ir;
|
||||
for(int i = 0; i < 3; i++) ir[i] = m_axis[i].xl(r[i]);
|
||||
return ir;
|
||||
|
||||
}
|
||||
|
||||
/// nearest Grid3D point
|
||||
inline gridvec_t ptn(const posvec_t& r){
|
||||
|
||||
gridvec_t ir;
|
||||
for(int i = 0; i < 3; i++) ir[i] = m_axis[i].xn(r[i]);
|
||||
return ir;
|
||||
|
||||
}
|
||||
|
||||
/// r coordinate of a Grid3D point
|
||||
inline posvec_t ptr(const gridvec_t& ir){
|
||||
|
||||
posvec_t r;
|
||||
for(int i = 0; i < 3; i++) r[i] = m_axis[i].m_coord[ir[i]];
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
inline posvec_t ptr(int ix, int iy, int iz){
|
||||
posvec_t r;
|
||||
r[0] = m_axis[0].m_coord[ix];
|
||||
r[1] = m_axis[1].m_coord[iy];
|
||||
r[2] = m_axis[2].m_coord[iz];
|
||||
return r;
|
||||
}
|
||||
|
||||
double put(xmlNodePtr cur, double epsbym){
|
||||
|
||||
double units; /// conversion unit
|
||||
|
||||
const double aB = 0.5291772108e-10; /// Bohr radius in meters
|
||||
const double aBeff = epsbym * aB;
|
||||
|
||||
const double u0 = 1.0/aBeff;
|
||||
|
||||
/// read in the units
|
||||
string cname ((const char*)(cur->name));
|
||||
if( cname == "Grid3D"){
|
||||
string cunit = (char*)xmlGetProp(cur,(xmlChar*)"unit");
|
||||
if(cunit == "nm"){
|
||||
units = u0 * 1.0e-9;
|
||||
cout << "The input data are expressed in nano-meters. " << endl;
|
||||
cout << "Using a.u. :: 1nm = " << units << " a_B*, and 1 a_B* = "
|
||||
<< aBeff << " m" << endl;
|
||||
} else if(cunit == "A"){
|
||||
units = u0 * 1.0e-10;
|
||||
cout << "The input data are expressed in Angstroms. " << endl;
|
||||
cout << "Using a.u. :: 1A = " << units << " a_B* " << endl;
|
||||
} else if(cunit == "au"){
|
||||
units = u0 * aB;
|
||||
cout << "The input data are expressed in atomic units. " << endl;
|
||||
cout << "Using a.u. :: 1 a_B = " << units << " a_B* " << endl;
|
||||
} else {
|
||||
units = 1.0;
|
||||
cout << "The input data are expressed in effective au. " << endl;
|
||||
cout << "Using a.u. :: 1nm = 1 a_B = 5.291772083(19)e-11m" << endl;
|
||||
}
|
||||
|
||||
vector<int> n_rho;
|
||||
vector<double> d_h;
|
||||
|
||||
xmlNodePtr node1 = cur->xmlChildrenNode; /// node1->name = Grid1D
|
||||
|
||||
while( node1 != NULL ){
|
||||
string name1 ((const char*)(node1->name));
|
||||
if( name1 == "Grid1D" ){
|
||||
|
||||
/// axis number
|
||||
int dir = atoi((char*)xmlGetProp(node1,(xmlChar*)"dir"));
|
||||
|
||||
/// number of sections
|
||||
int nsecs = atoi((char*)xmlGetProp(node1,(xmlChar*)"nsecs"));
|
||||
|
||||
/// total number of points
|
||||
int npts = atoi((char*)xmlGetProp(node1,(xmlChar*)"npts"));
|
||||
|
||||
/// coordinate origin
|
||||
double x0 = units * atof((char*)xmlGetProp(node1,(xmlChar*)"x0"));
|
||||
|
||||
/// assign the Grid::initialisation-vectors
|
||||
n_rho.resize(nsecs); d_h.resize(nsecs);
|
||||
|
||||
/// initilaise section to be read in.
|
||||
int isec = 0;
|
||||
|
||||
xmlNodePtr node2 = node1->xmlChildrenNode;
|
||||
while( node2 != NULL ){
|
||||
string name2 ((const char*)(node2->name));
|
||||
if( name2 == "section" ){
|
||||
n_rho[isec]=atoi((char*)xmlGetProp(node2,(xmlChar*)"nx"));
|
||||
d_h[isec]=units*atof((char*)xmlGetProp(node2,(xmlChar*)"dx"));
|
||||
isec++;
|
||||
}
|
||||
node2 = node2->next; /// next section if any
|
||||
}
|
||||
|
||||
/// initialise axis
|
||||
m_axis[dir].init(nsecs,npts,x0,n_rho,d_h);
|
||||
|
||||
}
|
||||
|
||||
node1 = node1->next; /// next Grid1D if any
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
cout << "Grid3D not properly supplied. Exiting ... " << endl;
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
set_size(); /// set all dimension sizes
|
||||
|
||||
return units;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
#include "Numerics/Spline3D/NRCubicSpline.h"
|
||||
|
||||
|
||||
void NRCubicSpline::update(){
|
||||
|
||||
double qn, un;
|
||||
std::vector<double> u(n_x-1);
|
||||
|
||||
|
||||
|
||||
/// set lower boundary condition
|
||||
if( y1i > y1max ){
|
||||
y2[0] = 0.0; u[0] = 0.0;
|
||||
} else {
|
||||
y2[0] = -0.5;
|
||||
u[0] = 3.0 * hin * ( y[1] - y[0] ) / ( h - y1i);
|
||||
}
|
||||
|
||||
/// decomposition loop of the tridiagonal matrix
|
||||
for(int i = 1; i < n_x - 1; i++){
|
||||
double sig = 0.5;
|
||||
double p = sig * y2[i-1] + 2.0;
|
||||
double pin = 1.0/p;
|
||||
y2[i] = (sig - 1.0) * pin;
|
||||
u[i] = hin * ( y[i+1] - 2.0 * y[i] + y[i-1] );
|
||||
u[i] = pin * ( 3 * hin * u[i] - sig * u[i-1] );
|
||||
}
|
||||
|
||||
if( y1f > y1max ){
|
||||
qn = 0.0; un = 0.0;
|
||||
} else {
|
||||
qn = 0.5;
|
||||
un = 3.0 * hin * ( y1f - hin * ( y[n_x-1] - y[n_x-2] ) );
|
||||
}
|
||||
|
||||
/// backsubstitution loop
|
||||
y2[n_x-1] = ( un - qn * u[n_x-2] ) / ( qn * y2[n_x-2] + 1.0 );
|
||||
for( int i = n_x - 2; i >= 0; i--)
|
||||
y2[i] = y2[i] * y2[i+1] + u[i];
|
||||
|
||||
UpToDate = true;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
double NRCubicSpline::evaluate( const double x,
|
||||
double& gradf){
|
||||
|
||||
if(! UpToDate ) update();
|
||||
double onesixth = 1.0/6.0;
|
||||
int ix = m_grid->xl(x);
|
||||
double a = hin * ( m_grid->m_coord[ix+1] - x );
|
||||
double b = hin * ( x - m_grid->m_coord[ix] );
|
||||
double yval = a * y[ix] + b * y[ix+1] + ( a * ( a * a - 1.0 ) * y2[ix] +
|
||||
b * ( b * b - 1.0 ) * y2[ix+1] ) *
|
||||
h * h * onesixth;
|
||||
|
||||
gradf = hin * ( y[ix+1] - y[ix] ) + onesixth * h *
|
||||
( ( 3.0 * b * b - 1.0 ) * y2[ix+1] - ( 3.0 * a * a - 1.0 ) * y2[ix] );
|
||||
|
||||
|
||||
|
||||
return yval;
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef GUARD_NRCUBICSPLINE_H
|
||||
#define GUARD_NRCUBICSPLINE_H
|
||||
|
||||
#include "Numerics/Spline3D/Config.h"
|
||||
#include "Numerics/Spline3D/uGrid1D.h"
|
||||
#include <vector>
|
||||
|
||||
class NRCubicSpline{
|
||||
|
||||
|
||||
/// default value of y1max
|
||||
double y1max;
|
||||
|
||||
/// initial first derivative
|
||||
double y1i;
|
||||
|
||||
/// final first derivative
|
||||
double y1f;
|
||||
|
||||
/// function value
|
||||
std::vector<double> y;
|
||||
|
||||
/// second derivative
|
||||
std::vector<double> y2;
|
||||
|
||||
void update();
|
||||
|
||||
public:
|
||||
|
||||
typedef double value_type;
|
||||
|
||||
/// uniform Grid1D
|
||||
uGrid1D* m_grid;
|
||||
|
||||
/// Constructor
|
||||
CubicSpline(uGrid1D* agrid){
|
||||
|
||||
m_grid = agrid;
|
||||
n_x = agrid->m_size;
|
||||
h = agrid->m_h;
|
||||
hin = 1.0/h;
|
||||
|
||||
y.resize(n_x); y2.resize(n_x);
|
||||
|
||||
y1max = 1.e30; y1i = y1max; y1f = y1max;
|
||||
|
||||
UpToDate = false;
|
||||
|
||||
}
|
||||
|
||||
/// set boundary conditions on first derivatives
|
||||
inline void set_bc(double ypi, double ypf){ y1i = ypi; y1f = ypf; }
|
||||
|
||||
|
||||
inline evaluate(const double, double&);
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef GUARD_SETSPLINEPOINT_H
|
||||
#define GUARD_SETSPLINEPOINT_H
|
||||
|
||||
#include "Numerics/Spline3D/Config.h"
|
||||
#include "Numerics/Spline3D/Grid3D.h"
|
||||
|
||||
class SetSplinePoint{
|
||||
|
||||
public:
|
||||
|
||||
bool ifout;
|
||||
int ix,iy,iz;
|
||||
double h,k,l;
|
||||
double hinv,kinv,linv;
|
||||
double u,v,w;
|
||||
|
||||
void set_point(const posvec_t& r,
|
||||
Grid3D* agrid){
|
||||
|
||||
gridvec_t ir = agrid->ptl(r);
|
||||
|
||||
ix = ir[0];
|
||||
iy = ir[1];
|
||||
iz = ir[2];
|
||||
|
||||
ifout = false;
|
||||
|
||||
if( r[2] < agrid->m_axis[2].m_start || r[0] > agrid->m_axis[0].m_end ||
|
||||
r[2] > agrid->m_axis[2].m_end || r[0] < agrid->m_axis[0].m_start ||
|
||||
r[1] < agrid->m_axis[1].m_start || r[1] > agrid->m_axis[1].m_end )
|
||||
{ ifout = true;
|
||||
/*
|
||||
cout << "OUTSIDE" << endl;
|
||||
cout << r[0] << '\t' << agrid->m_axis[0].m_start << '\t'
|
||||
<< agrid->m_axis[0].m_end << endl;
|
||||
cout << r[1] << '\t' << agrid->m_axis[1].m_start << '\t'
|
||||
<< agrid->m_axis[1].m_end << endl;
|
||||
cout << r[2] << '\t' << agrid->m_axis[2].m_start << '\t'
|
||||
<< agrid->m_axis[2].m_end << endl;
|
||||
*/
|
||||
}
|
||||
|
||||
h = agrid->m_axis[0].h(ix);
|
||||
k = agrid->m_axis[1].h(iy);
|
||||
l = agrid->m_axis[2].h(iz);
|
||||
|
||||
hinv = 1.0/h;
|
||||
kinv = 1.0/k;
|
||||
linv = 1.0/l;
|
||||
|
||||
u = (r[0] - agrid->m_axis[0].m_coord[ix])*hinv;
|
||||
v = (r[1] - agrid->m_axis[1].m_coord[iy])*kinv;
|
||||
w = (r[2] - agrid->m_axis[2].m_coord[iz])*linv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,361 @@
|
|||
#include "Numerics/Spline3D/TriCubicSpline.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void TriCubicSpline::Update(bool iflap){
|
||||
|
||||
UpdateX(0, 1); // Do dF/dx
|
||||
UpdateY(0, 2); // Do dF/dy
|
||||
UpdateZ(0, 3); // Do dF/dz
|
||||
UpdateY(1, 4); // Do d2F/dxdy
|
||||
UpdateZ(1, 5); // Do d2F/dxdz
|
||||
UpdateZ(2, 6); // Do d2F/dydz
|
||||
UpdateZ(4, 7); // Do d3F/dxdydz
|
||||
|
||||
if(iflap){
|
||||
|
||||
D2F.resize(n_x,n_y,n_z);
|
||||
/// calculate D2F at all points.
|
||||
D2FDR2();
|
||||
|
||||
UpdateD2X(0, 1); // Do d (D2F) /dx
|
||||
UpdateD2Y(0, 2); // Do d (D2F) /dy
|
||||
UpdateD2Z(0, 3); // Do d (D2F) /dy
|
||||
UpdateD2Y(1, 4); // Do d2 (D2F) /dxdy
|
||||
UpdateD2Z(1, 5); // Do d2 (D2F) /dxdz
|
||||
UpdateD2Z(2, 6); // Do d2 (D2F) /dydz
|
||||
UpdateD2Z(4, 7); // Do d3 (D2F) /dxdydz
|
||||
|
||||
}
|
||||
|
||||
UpToDate = true;
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateX(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_x);
|
||||
|
||||
/// Loop over all y and z
|
||||
for(int iy = 0; iy < n_y; iy++){
|
||||
for(int iz = 0; iz < n_z; iz++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
F(0,iy,iz)[dest] = 1.5 *
|
||||
( F(1,iy,iz)[source] - F(0,iy,iz)[source] ) / dx(0,0);
|
||||
F(n_x-1,iy,iz)[dest] = 1.5 *
|
||||
(F(n_x-1,iy,iz)[source] - F(n_x-2,iy,iz)[source]) / dx(0,n_x-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_x - 1; j++){
|
||||
double lambda = 0.5*dx(0,j)/(dx(0,j)+dx(0,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(j,iy,iz)[dest] =
|
||||
3.0*(lambda*(F(j,iy,iz)[source]-F(j-1,iy,iz)[source])/dx(0,j-1)+
|
||||
mu(j) *(F(j+1,iy,iz)[source]-F(j,iy,iz)[source])/dx(0,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(j,iy,iz)[dest] -= lambda * F(j-1,iy,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
F(j,iy,iz)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_x - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(j,iy,iz)[dest] =
|
||||
3.0*(lambda*(F(j,iy,iz)[source]-F(j-1,iy,iz)[source])/dx(0,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(j,iy,iz)[dest] -= lambda * F(j-1,iy,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
F(j,iy,iz)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_x-2; j>=0; j--)
|
||||
F(j,iy,iz)[dest] -= mu(j) * F(j+1,iy,iz)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateY(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_y);
|
||||
/// Loop over all x and z
|
||||
for(int ix = 0; ix < n_x; ix++){
|
||||
for(int iz = 0; iz < n_z; iz++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
F(ix,0,iz)[dest] = 1.5 *
|
||||
( F(ix,1,iz)[source] - F(ix,0,iz)[source] ) / dx(1,0);
|
||||
F(ix,n_y-1,iz)[dest] = 1.5 *
|
||||
(F(ix,n_y-1,iz)[source] - F(ix,n_y-2,iz)[source]) / dx(1,n_y-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_y - 1; j++){
|
||||
double lambda = 0.5*dx(1,j)/(dx(1,j)+dx(1,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(ix,j,iz)[dest] =
|
||||
3.0*(lambda*(F(ix,j,iz)[source]-F(ix,j-1,iz)[source])/dx(1,j-1)+
|
||||
mu(j) *(F(ix,j+1,iz)[source]-F(ix,j,iz)[source])/dx(1,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(ix,j,iz)[dest] -= lambda * F(ix,j-1,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
F(ix,j,iz)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_y - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(ix,j,iz)[dest] =
|
||||
3.0*(lambda*(F(ix,j,iz)[source]-F(ix,j-1,iz)[source])/dx(1,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(ix,j,iz)[dest] -= lambda * F(ix,j-1,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
F(ix,j,iz)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_y-2; j>=0; j--)
|
||||
F(ix,j,iz)[dest] -= mu(j) * F(ix,j+1,iz)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateZ(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_z);
|
||||
/// Loop over all x and y
|
||||
for(int ix = 0; ix < n_x; ix++){
|
||||
for(int iy = 0; iy < n_y; iy++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
F(ix,iy,0)[dest] = 1.5 *
|
||||
( F(ix,iy,1)[source] - F(ix,iy,0)[source] ) / dx(2,0);
|
||||
F(ix,iy,n_z-1)[dest] = 1.5 *
|
||||
(F(ix,iy,n_z-1)[source] - F(ix,iy,n_z-2)[source]) / dx(2,n_z-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_z - 1; j++){
|
||||
double lambda = 0.5*dx(2,j)/(dx(2,j)+dx(2,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(ix,iy,j)[dest] =
|
||||
3.0*(lambda*(F(ix,iy,j)[source]-F(ix,iy,j-1)[source])/dx(2,j-1)+
|
||||
mu(j) *(F(ix,iy,j+1)[source]-F(ix,iy,j)[source])/dx(2,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(ix,iy,j)[dest] -= lambda * F(ix,iy,j-1)[dest];
|
||||
mu(j) /= cj;
|
||||
F(ix,iy,j)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_z - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
F(ix,iy,j)[dest] =
|
||||
3.0*(lambda*(F(ix,iy,j)[source]-F(ix,iy,j-1)[source])/dx(2,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
F(ix,iy,j)[dest] -= lambda * F(ix,iy,j-1)[dest];
|
||||
mu(j) /= cj;
|
||||
F(ix,iy,j)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_z-2; j>=0; j--)
|
||||
F(ix,iy,j)[dest] -= mu(j) * F(ix,iy,j+1)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateD2X(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_x);
|
||||
/// Loop over all y and z
|
||||
for(int iy = 0; iy < n_y; iy++){
|
||||
for(int iz = 0; iz < n_z; iz++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
D2F(0,iy,iz)[dest] = 1.5 *
|
||||
( D2F(1,iy,iz)[source] - D2F(0,iy,iz)[source] ) / dx(0,0);
|
||||
D2F(n_x-1,iy,iz)[dest] = 1.5 *
|
||||
(D2F(n_x-1,iy,iz)[source] - D2F(n_x-2,iy,iz)[source]) / dx(0,n_x-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_x - 1; j++){
|
||||
double lambda = 0.5*dx(0,j)/(dx(0,j)+dx(0,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(j,iy,iz)[dest] =
|
||||
3.0*(lambda*(D2F(j,iy,iz)[source]-D2F(j-1,iy,iz)[source])/dx(0,j-1)+
|
||||
mu(j) *(D2F(j+1,iy,iz)[source]-D2F(j,iy,iz)[source])/dx(0,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(j,iy,iz)[dest] -= lambda * D2F(j-1,iy,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(j,iy,iz)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_x - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(j,iy,iz)[dest] =
|
||||
3.0*(lambda*(D2F(j,iy,iz)[source]-D2F(j-1,iy,iz)[source])/dx(0,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(j,iy,iz)[dest] -= lambda * D2F(j-1,iy,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(j,iy,iz)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_x-2; j>=0; j--)
|
||||
D2F(j,iy,iz)[dest] -= mu(j) * D2F(j+1,iy,iz)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateD2Y(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_y);
|
||||
/// Loop over all x and z
|
||||
for(int ix = 0; ix < n_x; ix++){
|
||||
for(int iz = 0; iz < n_z; iz++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
D2F(ix,0,iz)[dest] = 1.5 *
|
||||
( D2F(ix,1,iz)[source] - D2F(ix,0,iz)[source] ) / dx(1,0);
|
||||
D2F(ix,n_y-1,iz)[dest] = 1.5 *
|
||||
(D2F(ix,n_y-1,iz)[source] - D2F(ix,n_y-2,iz)[source]) / dx(1,n_y-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_y - 1; j++){
|
||||
double lambda = 0.5*dx(1,j)/(dx(1,j)+dx(1,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(ix,j,iz)[dest] =
|
||||
3.0*(lambda*(D2F(ix,j,iz)[source]-D2F(ix,j-1,iz)[source])/dx(1,j-1)+
|
||||
mu(j) *(D2F(ix,j+1,iz)[source]-D2F(ix,j,iz)[source])/dx(1,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(ix,j,iz)[dest] -= lambda * D2F(ix,j-1,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(ix,j,iz)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_y - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(ix,j,iz)[dest] =
|
||||
3.0*(lambda*(D2F(ix,j,iz)[source]-D2F(ix,j-1,iz)[source])/dx(1,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(ix,j,iz)[dest] -= lambda * D2F(ix,j-1,iz)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(ix,j,iz)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_y-2; j>=0; j--)
|
||||
D2F(ix,j,iz)[dest] -= mu(j) * D2F(ix,j+1,iz)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::UpdateD2Z(int source, int dest){
|
||||
|
||||
blitz::Array<double,1> mu(n_z);
|
||||
/// Loop over all x and y
|
||||
for(int ix = 0; ix < n_x; ix++){
|
||||
for(int iy = 0; iy < n_y; iy++){
|
||||
|
||||
/// set up tridiagonal set of equations : initialise RHS
|
||||
D2F(ix,iy,0)[dest] = 1.5 *
|
||||
( D2F(ix,iy,1)[source] - D2F(ix,iy,0)[source] ) / dx(2,0);
|
||||
D2F(ix,iy,n_z-1)[dest] = 1.5 *
|
||||
(D2F(ix,iy,n_z-1)[source] - D2F(ix,iy,n_z-2)[source]) / dx(2,n_z-2);
|
||||
mu(0) = 0.5;
|
||||
|
||||
/// solve tri-diagonal set of equations. First eliminate lower elements
|
||||
for(int j = 1; j < n_z - 1; j++){
|
||||
double lambda = 0.5*dx(2,j)/(dx(2,j)+dx(2,j-1));
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(ix,iy,j)[dest] =
|
||||
3.0*(lambda*(D2F(ix,iy,j)[source]-D2F(ix,iy,j-1)[source])/dx(2,j-1)+
|
||||
mu(j) *(D2F(ix,iy,j+1)[source]-D2F(ix,iy,j)[source])/dx(2,j) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(ix,iy,j)[dest] -= lambda * D2F(ix,iy,j-1)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(ix,iy,j)[dest] /= cj;
|
||||
}
|
||||
|
||||
/// last element
|
||||
int j = n_z - 1;
|
||||
double lambda = 0.5;
|
||||
mu(j) = 0.5 - lambda;
|
||||
D2F(ix,iy,j)[dest] =
|
||||
3.0*(lambda*(D2F(ix,iy,j)[source]-D2F(ix,iy,j-1)[source])/dx(2,j-1) );
|
||||
double cj = 1.0 - lambda * mu(j-1);
|
||||
D2F(ix,iy,j)[dest] -= lambda * D2F(ix,iy,j-1)[dest];
|
||||
mu(j) /= cj;
|
||||
D2F(ix,iy,j)[dest] /= cj;
|
||||
|
||||
/// now last d/dx is correct, so proceed upward, back substituting
|
||||
for (j=n_z-2; j>=0; j--)
|
||||
D2F(ix,iy,j)[dest] -= mu(j) * D2F(ix,iy,j+1)[dest];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSpline::D2FDR2(){
|
||||
|
||||
D2F = 0.0;
|
||||
for(int ix = 1; ix < n_x - 1; ix++){
|
||||
for(int iy = 1; iy < n_y - 1; iy++){
|
||||
for(int iz = 1; iz < n_z - 1; iz++){
|
||||
posvec_t r = m_grid->ptr(ix,iy,iz);
|
||||
D2F(ix,iy,iz)[0] = laplacian(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
double TriCubicSpline::delsqf(const gridvec_t& P0, int dir){
|
||||
|
||||
double numer, denom;
|
||||
gridvec_t Pi,Pf;
|
||||
|
||||
for(int idim = 0; idim < 3; idim++){
|
||||
Pi[idim] = P0[idim]; Pf[idim] = P0[idim];
|
||||
}
|
||||
Pi[dir] -= 1; Pf[dir] += 1;
|
||||
|
||||
double f0 = F(P0[0],P0[1],P0[2])[0];
|
||||
|
||||
double fi = F(Pi[0],Pi[1],Pi[2])[0];
|
||||
double ff = F(Pf[0],Pf[1],Pf[2])[0];
|
||||
|
||||
double hi = dx(dir,Pi[dir]);
|
||||
double h0 = dx(dir,P0[dir]);
|
||||
|
||||
numer = hi*(ff-f0) + h0*(fi-f0);
|
||||
denom = hi*h0*(hi+h0);
|
||||
|
||||
return 2.0*numer/(denom+1e-30);
|
||||
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,136 @@
|
|||
#include "Numerics/Spline3D/TriCubicSplineSet.h"
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
namespace ohmmsqmc {
|
||||
|
||||
using namespace std;
|
||||
|
||||
TriCubicSplineSet::TriCubicSplineSet(): DeviceGrid(NULL),
|
||||
Schr_Grid(NULL),
|
||||
m_set(NULL){ }
|
||||
|
||||
TriCubicSplineSet::~TriCubicSplineSet(){
|
||||
}
|
||||
|
||||
bool TriCubicSplineSet::put(xmlNodePtr cur,
|
||||
Grid3D* agrid){
|
||||
|
||||
/// make these member functions (WHY???)
|
||||
vector<string> wfile;
|
||||
vector<int> norbs_t;
|
||||
|
||||
DeviceGrid = agrid; /// point to the whole Grid3D
|
||||
if(!m_set) m_set = new SetSplinePoint; /// create r-point set
|
||||
|
||||
xmlNodePtr node = cur->xmlChildrenNode;
|
||||
while( node != NULL){
|
||||
string name((char*)node->name);
|
||||
if(name=="orbitals"){
|
||||
int n = atoi((char*)xmlGetProp(node,(xmlChar*)"norbs"));
|
||||
string w((char*)xmlGetProp(node,(xmlChar*)"file"));
|
||||
norbs_t.push_back(n);
|
||||
wfile.push_back(w);
|
||||
}
|
||||
if(name=="HeteroStructure"){
|
||||
xmlNodePtr node1 = node->xmlChildrenNode;
|
||||
while(node1 != NULL){
|
||||
string cname((const char*)(node1->name));
|
||||
if(cname=="Grid3D"){
|
||||
xmlNodePtr node2 = node1->xmlChildrenNode;
|
||||
while(node2 != NULL){
|
||||
string qname((const char*)(node2->name));
|
||||
if(qname=="qGridi"){
|
||||
ri[0] = atoi((char*)xmlGetProp(node2,(xmlChar*)"x"));
|
||||
ri[1] = atoi((char*)xmlGetProp(node2,(xmlChar*)"y"));
|
||||
ri[2] = atoi((char*)xmlGetProp(node2,(xmlChar*)"z"));
|
||||
}
|
||||
if(qname=="qGridf"){
|
||||
rf[0] = atoi((char*)xmlGetProp(node2,(xmlChar*)"x"));
|
||||
rf[1] = atoi((char*)xmlGetProp(node2,(xmlChar*)"y"));
|
||||
rf[2] = atoi((char*)xmlGetProp(node2,(xmlChar*)"z"));
|
||||
}
|
||||
node2 = node2->next;
|
||||
}
|
||||
}
|
||||
node1 = node1->next;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
|
||||
/// allocate and initialise the Schr_Grid
|
||||
if(!Schr_Grid) Schr_Grid = new Grid3D;
|
||||
Schr_Grid->init(ri,rf,DeviceGrid);
|
||||
|
||||
/// read in the input wave-function file
|
||||
norbs = 0; cout << "Reading Wafefunction file ..." ;
|
||||
for(int iset=0; iset<wfile.size(); iset++) {
|
||||
for(int iorb = 0; iorb < norbs_t[iset]; iorb++) {
|
||||
m_psi.push_back(new TriCubicSpline(m_set,Schr_Grid));
|
||||
}
|
||||
readwf(wfile[iset].c_str(),iset,norbs_t[iset]);
|
||||
}
|
||||
cout << "done!" << endl;
|
||||
|
||||
if(wfile.size() ==1) {
|
||||
char aname[4];
|
||||
int num = orbital_map.size();
|
||||
for(int iorb = 0; iorb < num; iorb++) {
|
||||
sprintf(aname,"d%d",iorb);
|
||||
orbital_map[aname]=iorb;
|
||||
}
|
||||
}
|
||||
|
||||
/// initialise the TriCubicSpline
|
||||
for(int iorb = 0; iorb < m_psi.size(); iorb++)
|
||||
m_psi[iorb]->Update(true); /// Laplacian is required so true
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void TriCubicSplineSet::readwf(const char* wfile, int ispin, int num){
|
||||
|
||||
char aname[4];
|
||||
int norbs_save = norbs;
|
||||
|
||||
for(int iorb = 0; iorb < num; iorb++) {
|
||||
if(ispin == 0) {
|
||||
sprintf(aname,"u%d",iorb);
|
||||
orbital_map[aname]=norbs++;
|
||||
} else {
|
||||
sprintf(aname,"d%d",iorb);
|
||||
orbital_map[aname]=norbs++;
|
||||
}
|
||||
}
|
||||
|
||||
ifstream infile(wfile, ios_base::in); double x;
|
||||
for(int i = 0; i < Schr_Grid->m_size; i++){
|
||||
for(int iorb = norbs_save, j=0; j< num; iorb++,j++) {
|
||||
infile >>x;
|
||||
const gridvec_t& ir = Schr_Grid->ipt(i);
|
||||
(*m_psi[iorb])(ir[0],ir[1],ir[2]) = -x;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TriCubicSplineSet::evaluate(const posvec_t& r,
|
||||
scalar_array_t& fval,
|
||||
posarray_t& gradf,scalar_array_t& lapf){
|
||||
for(int iorb = 0; iorb < norbs; iorb++)
|
||||
fval[iorb] = m_psi[iorb]->evaluate(r,gradf[iorb],lapf[iorb]);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue