├── .gitignore ├── CMakeLists.txt ├── README.rst ├── cmake ├── FindSphinx.cmake ├── download_eigen3.in ├── download_gtest.in └── download_pybind11.in ├── docs_source ├── CMakeLists.txt ├── doxygen │ ├── Doxyfile.in │ └── DoxygenLayout.xml └── sphinx │ ├── c_losc.rst │ ├── conf.py │ ├── index.rst │ ├── installation.rst │ ├── introduction.rst │ ├── losc.rst │ ├── psi4_api_ref__psi4_losc.rst │ ├── psi4_api_ref__psi4_losc__scf.rst │ ├── psi4_losc.rst │ └── py_losc.rst ├── include ├── c_losc │ ├── correction.h │ ├── curvature.h │ ├── local_occupation.h │ ├── localization.h │ ├── losc.h │ └── matrix.h └── losc │ ├── correction.hpp │ ├── curvature.hpp │ ├── eigen_def.hpp │ ├── exception.hpp │ ├── local_occupation.hpp │ ├── localization.hpp │ └── losc.hpp ├── src ├── CMakeLists.txt ├── c_losc │ ├── CMakeLists.txt │ ├── correction.cpp │ ├── curvature.cpp │ ├── local_occupation.cpp │ ├── localization.cpp │ ├── matrix.cpp │ └── matrix_impl.hpp ├── losc │ ├── CMakeLists.txt │ ├── correction.cpp │ ├── curvature.cpp │ ├── curvature_v1.cpp │ ├── curvature_v2.cpp │ ├── eigen_helper.hpp │ ├── exception.cpp │ ├── local_occupation.cpp │ ├── localization.cpp │ └── localization_v2.cpp ├── psi4_losc │ ├── CMakeLists.txt │ ├── __init__.py │ ├── build_scf_wfn.py │ ├── diis.py │ ├── jk.py │ ├── losc_options.py │ ├── psi4_losc.py │ ├── scf.py │ └── utils.py ├── py_losc │ ├── CMakeLists.txt │ ├── __init__.py │ ├── export_correction.cpp │ ├── export_correction.hpp │ ├── export_curvature.cpp │ ├── export_curvature.hpp │ ├── export_local_occupation.cpp │ ├── export_local_occupation.hpp │ ├── export_localization.cpp │ ├── export_localization.hpp │ ├── export_py_losc.cpp │ ├── export_py_losc.hpp │ └── py_losc.py └── pyscf_losc │ ├── CMakeLists.txt │ ├── __init__.py │ ├── losc_options.py │ ├── pyscf_losc.py │ └── utils.py └── tests ├── CMakeLists.txt ├── losc ├── CMakeLists.txt ├── correction_test.cpp ├── curvature_test.cpp ├── data │ ├── H2.10A │ │ ├── ao_overlap.txt │ │ ├── df_Vpq_inv.txt │ │ ├── df_pmn.txt │ │ ├── dfa_density.txt │ │ ├── dfa_h.txt │ │ ├── dipole_ao.txt │ │ ├── energy.txt │ │ ├── grid_basis.txt │ │ ├── grid_wt.txt │ │ ├── kappa.txt │ │ ├── lo.txt │ │ ├── lo_basis.txt │ │ ├── localocc.txt │ │ ├── losc_H_corr.txt │ │ ├── losc_eig.txt │ │ ├── mol.inp │ │ ├── mol.xyz │ │ └── u.txt │ ├── H2.1A │ │ ├── ao_overlap.txt │ │ ├── df_Vpq_inv.txt │ │ ├── df_pmn.txt │ │ ├── dfa_density.txt │ │ ├── dfa_h.txt │ │ ├── dipole_ao.txt │ │ ├── energy.txt │ │ ├── grid_basis.txt │ │ ├── grid_wt.txt │ │ ├── kappa.txt │ │ ├── lo.txt │ │ ├── lo_basis.txt │ │ ├── localocc.txt │ │ ├── losc_H_corr.txt │ │ ├── losc_eig.txt │ │ ├── mol.inp │ │ ├── mol.xyz │ │ └── u.txt │ └── H2O │ │ ├── ao_overlap.txt │ │ ├── df_Vpq_inv.txt │ │ ├── df_pmn.txt │ │ ├── dfa_density.txt │ │ ├── dfa_h.txt │ │ ├── dipole_ao.txt │ │ ├── energy.txt │ │ ├── gamma=0.win=0_7.inp │ │ ├── gamma=0.win=5_7.inp │ │ ├── gamma=0.win=all.inp │ │ ├── gamma=default.win=0_7.inp │ │ ├── grid_basis.txt │ │ ├── grid_wt.txt │ │ ├── kappa.txt │ │ ├── lo.gamma=0.win=0_7.txt │ │ ├── lo.gamma=0.win=5_7.txt │ │ ├── lo.gamma=0.win=all.txt │ │ ├── lo.gamma=default.win=0_7.txt │ │ ├── lo.txt │ │ ├── lo_basis.gamma=0.win=0_7.txt │ │ ├── lo_basis.gamma=0.win=5_7.txt │ │ ├── lo_basis.gamma=0.win=all.txt │ │ ├── lo_basis.gamma=default.win=0_7.txt │ │ ├── lo_basis.txt │ │ ├── localocc.txt │ │ ├── losc_H_corr.txt │ │ ├── losc_eig.txt │ │ ├── mol.inp │ │ ├── mol.xyz │ │ ├── u.gamma=0.win=0_7.txt │ │ ├── u.gamma=0.win=5_7.txt │ │ ├── u.gamma=0.win=all.txt │ │ ├── u.gamma=default.win=0_7.txt │ │ └── u.txt ├── local_occ_test.cpp ├── localization_test.cpp ├── matrix_checker_test.cpp ├── matrix_helper.cpp ├── matrix_helper.hpp ├── matrix_io.cpp └── matrix_io.hpp └── psi4_losc ├── test_frac_scf.py ├── test_occ.py ├── test_post_scf_losc.py ├── test_scf.py └── test_scf_losc.py /.gitignore: -------------------------------------------------------------------------------- 1 | # build dir and files. 2 | *build*/ 3 | docs/build* 4 | 5 | # vscode 6 | *.vscode/ 7 | 8 | # googletest 9 | googletest/ 10 | 11 | # test data output file 12 | **/tests/**/*.bin 13 | **/tests/**/*.out 14 | **/tests/*.sh 15 | 16 | # extern 17 | extern*/ 18 | 19 | **/*.so 20 | **/tmp_* 21 | **/__pycache__ 22 | 23 | # psi4 24 | **/*.out 25 | **/*.clean 26 | **/*.dat 27 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | # names of projects 4 | set(PROJECT_LOSC losc) 5 | project(${PROJECT_LOSC} C CXX) 6 | 7 | # C/C++ standard setting 8 | set(CMAKE_C_STANDARD 99) 9 | set(CMAKE_CXX_STANDARD 11) 10 | set(CMAKE_CXX_STANDARD_REQUIRED True) 11 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 12 | 13 | # Download pybind11 library 14 | set(PYBIND11_SOURCE_DIR "${CMAKE_SOURCE_DIR}/external/pybind11") 15 | if(NOT EXISTS "${PYBIND11_SOURCE_DIR}") 16 | message(STATUS "Downloading external library: pybind11.") 17 | configure_file(cmake/download_pybind11.in download/pybind11/CMakeLists.txt) 18 | execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . 19 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/pybind11" 20 | ) 21 | execute_process(COMMAND "${CMAKE_COMMAND}" --build . 22 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/pybind11" 23 | ) 24 | endif() 25 | 26 | # find Eigen3 library. 27 | find_package (Eigen3 NO_MODULE) 28 | if(Eigen3_FOUND) 29 | message(STATUS "Eigen3 library found.") 30 | else() 31 | # Download and build Eigen3 32 | message(STATUS "Downloading external library: Eigen3.") 33 | set(EXTERNAL_INSTALL_LOCATION "${CMAKE_SOURCE_DIR}/external") 34 | configure_file(cmake/download_eigen3.in download/eigen3/CMakeLists.txt) 35 | execute_process( 36 | COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . 37 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/eigen3" 38 | ) 39 | execute_process( 40 | COMMAND ${CMAKE_COMMAND} --build . 41 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/eigen3" 42 | ) 43 | # find Eigen3 again 44 | find_package (Eigen3 REQUIRED NO_MODULE) 45 | if(Eigen3_FOUND) 46 | message(STATUS "External Eigen3 library is installed.") 47 | else() 48 | message(FATAL_ERROR "Eigen3 library not found. Please install Eigen3 library.") 49 | endif() 50 | endif() 51 | 52 | # ==> build pybind11 <== 53 | add_subdirectory("${PYBIND11_SOURCE_DIR}") 54 | 55 | # ==> build source <== 56 | add_subdirectory(src) 57 | 58 | # ==> build tests <== 59 | option(BUILD_TEST "Build test or not." OFF) 60 | if (BUILD_TEST) 61 | enable_testing() 62 | # Download googletest library 63 | set(GOOGLE_TEST_SOURCE_DIR "${CMAKE_SOURCE_DIR}/external/googletest") 64 | if(NOT EXISTS "${GOOGLE_TEST_SOURCE_DIR}") 65 | message(STATUS "Downloading external library: googletest.") 66 | configure_file(cmake/download_gtest.in download/googletest/CMakeLists.txt) 67 | execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . 68 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/googletest" 69 | ) 70 | execute_process(COMMAND "${CMAKE_COMMAND}" --build . 71 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/download/googletest" 72 | ) 73 | endif() 74 | 75 | # build google test 76 | # Prevent overriding the parent project's compiler/linker 77 | # settings on Windows 78 | set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 79 | # Add googletest directly to our build. This defines 80 | # the gtest and gtest_main targets. 81 | add_subdirectory("${GOOGLE_TEST_SOURCE_DIR}") 82 | 83 | # build test source 84 | add_subdirectory(tests) 85 | else() 86 | message(STATUS "Note: Tests are disabled. Use \"-DBUILD_TEST=On\" to build tests.") 87 | endif() 88 | 89 | # ==> build docs <== 90 | option(BUILD_DOC "Build documentation for Losc library" OFF) 91 | if (BUILD_DOC) 92 | add_subdirectory(docs_source) 93 | else (BUILD_DOC) 94 | message("Note: If you want to build documentation, use `-DBUILD_DOC=On" 95 | "Doxygen will be required.") 96 | endif (BUILD_DOC) 97 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============================================ 2 | Localized Orbital Scaling Correction (LOSC) 3 | ============================================ 4 | 5 | LOSC is a newly developed method in `Weitao Yang's Research group 6 | `_ to solve the delocalization error 7 | for the density functional theory (DFT) in quantum chemistry. 8 | 9 | What does this Project do? 10 | ========================== 11 | 12 | - This project provides libraries with interfaces for popular programming 13 | languages in quantum chemistry, including C, C++ and Python, 14 | for the developers who would be interested to implement the LOSC method 15 | in their favorite quantum chemistry packages. These libraries 16 | provide the functionalities to perform the essential calculations of 17 | the LOSC method, such as constructing the LOs, LOSC curvature matrix, 18 | and LOSC corrections. 19 | 20 | - This project provides the implementation of LOSC method in an open-source 21 | quantum chemistry package, `psi4 `_, with its 22 | Python interface. If you are a user of psi4, you can directly use this 23 | library with psi4 to perform LOSC calculations. 24 | 25 | Manual and Documentation 26 | ======================== 27 | 28 | The manual and documentation are available at https://yang-laboratory.github.io/losc/. 29 | Refer to the website for the instructions of installation and usage. 30 | 31 | References of LOSC 32 | ================== 33 | 34 | - Li, C.; Zheng, X.; Su, N. Q.; Yang, W. Localized Orbital Scaling 35 | Correction for System- atic Elimination of Delocalization Error in 36 | Density Functional Approximations. 37 | `Natl. Sci. Rev. 2018, 5, 203−215. 203-215. 38 | `_ 39 | 40 | - Su, N. Q.; Mahler, A.; Yang, W. Preserving Symmetry and 41 | Degeneracy in the Localized Orbital Scaling Correction Approach. J. 42 | `Phys. Chem. Lett. 2020, 11, 1528−1535. 43 | `_ 44 | 45 | - Mei, Y.; Chen, Z.; Yang, W. 46 | Self-Consistent Calculation of the Localized Orbital Scaling Correction 47 | for Correct Electron Densities and Energy-Level Alignments in Density 48 | Functional Theory. 49 | `J. Phys. Chem. Lett. 2020, 11, 23, 10269–10277. 50 | `_ 51 | -------------------------------------------------------------------------------- /cmake/FindSphinx.cmake: -------------------------------------------------------------------------------- 1 | #Look for an executable called sphinx-build 2 | find_program(SPHINX_EXECUTABLE 3 | NAMES sphinx-build 4 | DOC "Path to sphinx-build executable") 5 | 6 | include(FindPackageHandleStandardArgs) 7 | 8 | #Handle standard arguments to find_package like REQUIRED and QUIET 9 | find_package_handle_standard_args(Sphinx 10 | "Failed to find sphinx-build executable" 11 | SPHINX_EXECUTABLE) 12 | -------------------------------------------------------------------------------- /cmake/download_eigen3.in: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(dl_eigen3 NONE) 3 | 4 | include(ExternalProject) 5 | ExternalProject_Add(eigen3 6 | GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git 7 | GIT_TAG 3.3.9 8 | CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION}/eigen3 9 | ) 10 | -------------------------------------------------------------------------------- /cmake/download_gtest.in: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(dl_gtest NONE) 3 | 4 | include(ExternalProject) 5 | ExternalProject_Add(googletest 6 | GIT_REPOSITORY https://github.com/google/googletest.git 7 | GIT_TAG "release-1.10.0" 8 | SOURCE_DIR "${CMAKE_SOURCE_DIR}/external/googletest" 9 | BINARY_DIR "${CMAKE_BINARY_DIR}/external/googletest" 10 | CONFIGURE_COMMAND "" 11 | BUILD_COMMAND "" 12 | INSTALL_COMMAND "" 13 | TEST_COMMAND "" 14 | ) 15 | -------------------------------------------------------------------------------- /cmake/download_pybind11.in: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(dl_pybind11 NONE) 3 | 4 | include(ExternalProject) 5 | ExternalProject_Add(pybind11 6 | GIT_REPOSITORY https://github.com/pybind/pybind11.git 7 | GIT_TAG v2.6.2 8 | SOURCE_DIR "${CMAKE_SOURCE_DIR}/external/pybind11" 9 | BINARY_DIR "${CMAKE_BINARY_DIR}/external/pybind11" 10 | CONFIGURE_COMMAND "" 11 | BUILD_COMMAND "" 12 | INSTALL_COMMAND "" 13 | TEST_COMMAND "" 14 | ) 15 | -------------------------------------------------------------------------------- /docs_source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # To use Sphinx + Breathe + Doxygen to generate documentations 2 | # for C/C++ project. Refer to this blog for an example: 3 | # https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/. 4 | # 5 | # I think doxygen generates the documentations for C/C++ in a better look 6 | # compared to sphinx. So I switch back to using doxygen. 7 | 8 | # Add the cmake folder, so the FindSphinx module can be found. 9 | set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) 10 | 11 | # require doxygen and sphinx is installed. 12 | find_package(Doxygen REQUIRED) 13 | find_package(Sphinx REQUIRED) 14 | 15 | # some variables used to configure sphinx source files. 16 | set(LOSC_DOXYGEN_HTML_OUTPUT "") 17 | set(C_LOSC_DOXYGEN_HTML_OUTPUT "") 18 | set(DOCS_OUTPUT_ROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/docs) 19 | set(DOCS_SOURCE_ROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src) 20 | file(MAKE_DIRECTORY ${DOCS_OUTPUT_ROOT_DIR}) 21 | file(MAKE_DIRECTORY ${DOCS_SOURCE_ROOT_DIR}) 22 | # To let github pages to host the docs and use the read-the-docs theme, 23 | # an empty `.nojekyll` file should be placed in the root dir of docs. 24 | file(TOUCH ${DOCS_OUTPUT_ROOT_DIR}/.nojekyll) 25 | 26 | # ==> Doxygen <== 27 | macro(build_doxygen module) 28 | set(DOXYGEN_SOURCE_ROOT_DIR ${DOCS_SOURCE_ROOT_DIR}/doxygen/${module}) 29 | set(DOXYGEN_INPUT_DIR ${CMAKE_SOURCE_DIR}/include/${module}) 30 | set(DOXYGEN_OUTPUT_DIR ${DOCS_OUTPUT_ROOT_DIR}/doxygen/${module}) 31 | set(DOXYGEN_HTML_OUTPUT_DIR ${DOXYGEN_OUTPUT_DIR}/html) 32 | set(DOXYGEN_HTML_OUTPUT ${DOXYGEN_HTML_OUTPUT_DIR}/index.html) 33 | set(DOXYGEN_LAYOUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/DoxygenLayout.xml) 34 | 35 | # create some directories that Doxygen won't create for us 36 | file(MAKE_DIRECTORY ${DOXYGEN_SOURCE_ROOT_DIR}) 37 | file(MAKE_DIRECTORY ${DOXYGEN_HTML_OUTPUT_DIR}) 38 | 39 | if ("${module}" STREQUAL "losc") 40 | set(DOXYGEN_PROJECT_NAME "\"Localized Orbital Scaling Correction (LOSC) C++ library\"") 41 | set(LOSC_DOXYGEN_HTML_OUTPUT ${DOXYGEN_HTML_OUTPUT}) 42 | elseif ("${module}" STREQUAL "c_losc") 43 | set(DOXYGEN_PROJECT_NAME "\"Localized Orbital Scaling Correction (LOSC) C library\"") 44 | set(C_LOSC_DOXYGEN_HTML_OUTPUT ${DOXYGEN_HTML_OUTPUT}) 45 | else() 46 | message(FATAL_ERROR "Unknown module to build docs: ${module}") 47 | endif() 48 | message(STATUS "Build docs for module: ${module}") 49 | 50 | # configure the configuration file for doxygen. 51 | file(GLOB DOXYGEN_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/*) 52 | file(COPY ${DOXYGEN_SOURCE_FILES} DESTINATION ${DOXYGEN_SOURCE_ROOT_DIR}) 53 | set(DOXYFILE_IN ${DOXYGEN_SOURCE_ROOT_DIR}/Doxyfile.in) 54 | set(DOXYFILE_OUT ${DOXYGEN_SOURCE_ROOT_DIR}/Doxyfile) 55 | configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) 56 | 57 | # print some informational message. 58 | message(STATUS "${module}: doxygen configuration file: ${DOXYFILE_OUT}") 59 | message(STATUS "${module}: DOXYGEN_INPUT_DIR: ${DOXYGEN_INPUT_DIR}") 60 | message(STATUS "${module}: DOXYGEN_SOURCE_ROOT_DIR: ${DOXYGEN_SOURCE_ROOT_DIR}") 61 | message(STATUS "${module}: DOXYGEN_HTML_OUTPUT: ${DOXYGEN_HTML_OUTPUT}") 62 | 63 | # build documentations for losc and c_losc modules with doxygen. 64 | add_custom_command(OUTPUT ${DOXYGEN_HTML_OUTPUT} 65 | DEPENDS 66 | ${DOXYGEN_INPUT_DIR} 67 | ${DOXYFILE_OUT} 68 | losc c_losc py_losc_core 69 | ${DOXYGEN_SOURCE_FILES} 70 | COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} 71 | MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} 72 | COMMENT "Generating docs with doxygen" 73 | ) 74 | 75 | # create a target for doxygen docs. 76 | add_custom_target(docs_doxygen_${module} ALL DEPENDS ${DOXYGEN_HTML_OUTPUT}) 77 | endmacro() 78 | 79 | # build docs for losc module 80 | build_doxygen("losc") 81 | 82 | # build docs for c_losc module 83 | build_doxygen("c_losc") 84 | 85 | message(STATUS "LOSC_DOXYGEN_HTML_OUTPUT: ${LOSC_DOXYGEN_HTML_OUTPUT}") 86 | message(STATUS "C_LOSC_DOXYGEN_HTML_OUTPUT: ${C_LOSC_DOXYGEN_HTML_OUTPUT}") 87 | 88 | # ==> Sphinx <== 89 | # Only regenerate Sphinx when: 90 | # - Doxygen has rerun 91 | # - Our doc files have been updated 92 | # - The Sphinx config has been updated 93 | set(SPHINX_HTML_OUTPUT ${DOCS_OUTPUT_ROOT_DIR}/index.html) 94 | set(SPHINX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sphinx) 95 | set(SPHINX_BUILD_DIR ${DOCS_OUTPUT_ROOT_DIR}) 96 | file(GLOB SPHINX_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/sphinx/*) 97 | file(GLOB SPHINX_PYTHON_SOURCE_FILES ${CMAKE_SOURCE_DIR}/src/**/*.py) 98 | add_custom_command(OUTPUT ${SPHINX_HTML_OUTPUT} 99 | COMMAND 100 | ${SPHINX_EXECUTABLE} -b html 101 | # Tell Breathe where to find the Doxygen output 102 | #-Dbreathe_projects.losc=${DOXYGEN_OUTPUT_DIR}/xml 103 | ${SPHINX_SOURCE_DIR} ${SPHINX_BUILD_DIR} 104 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 105 | DEPENDS 106 | # Other docs files you want to track should go here (or in some variable) 107 | ${SPHINX_SOURCE_FILES} 108 | ${SPHINX_PYTHON_SOURCE_FILES} 109 | losc 110 | c_losc 111 | py_losc_core 112 | MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/sphinx/conf.py 113 | COMMENT "Generating documentation with Sphinx") 114 | 115 | # create a target for sphinx docs. 116 | add_custom_target(dosc_sphinx ALL DEPENDS ${SPHINX_HTML_OUTPUT}) 117 | 118 | message(STATUS "Note: Enable to build the documentation.\n" 119 | " After the building process, see documentation in:\n" 120 | " ${DOCS_OUTPUT_ROOT_DIR}") 121 | -------------------------------------------------------------------------------- /docs_source/sphinx/c_losc.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | LOSC C library 3 | ============== 4 | 5 | Introduction 6 | ------------ 7 | 8 | The LOSC library provides a C interface to perform calculations of LOSC, 9 | including the construction of LOSC curvature matrix, LOSC localization, 10 | local occupation number and LOSC corrections. The C interface is developed 11 | by wrapping the :ref:`C++ interface ` in C-style. 12 | 13 | .. Warning:: Not sure about how to let C code handle the exceptions that may 14 | be thrown in the C++ code. 15 | 16 | The provided C interface (C header files) includes 17 | 18 | ================================ ====================================== 19 | Header Description 20 | ================================ ====================================== 21 | ```` provide the C interface for the matrix 22 | objects that are used in the LOSC library. 23 | ```` for the LOSC curvature matrix. 24 | ```` for the LOSC localization. 25 | ```` for the LOSC local occupation. 26 | ```` for the LOSC corrections. 27 | ```` A convenient header that includes 28 | everything you need. 29 | ================================ ====================================== 30 | 31 | In order to use the C interface of the LOSC library, following the 32 | :ref:`steps of installation `. Then all you 33 | need to do is to include the corresponding headers in your project 34 | to use the LOSC C library. 35 | 36 | 37 | Data Structure 38 | -------------- 39 | The LOSC C library defines matrix object with ``struct losc_matrix`` that is 40 | declared in ```` header. You can call the constructor function 41 | ``losc_matrix_create`` to create a ``struct losc_matrix`` with any size, 42 | or you can pass a C pointer ``double *`` that points to an array to generate a 43 | ``struct losc_matrix``, which does not own the data. Remember the storage of 44 | the matrix is ALWAYS interpreted in row-wise (C-style) major. See 45 | ```` for more details. 46 | 47 | Detailed References for the API 48 | ------------------------------- 49 | 50 | Please refer `this section <./doxygen/c_losc/html/index.html>`_ for the full 51 | documentation of C interface of the LOSC library. 52 | -------------------------------------------------------------------------------- /docs_source/sphinx/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'Localized Orbital Scaling Correction Library' 21 | copyright = '2021, Yuncai Mei' 22 | author = 'Yuncai Mei' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '0.0.1' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = ["sphinx.ext.autodoc", 34 | "sphinx.ext.napoleon", 35 | "sphinx.ext.viewcode", 36 | "sphinx_rtd_theme", 37 | 'sphinx.ext.autosectionlabel', 38 | #'breathe', 39 | ] 40 | 41 | # Add any paths that contain templates here, relative to this directory. 42 | templates_path = ['_templates'] 43 | 44 | # List of patterns, relative to source directory, that match files and 45 | # directories to ignore when looking for source files. 46 | # This pattern also affects html_static_path and html_extra_path. 47 | exclude_patterns = [] 48 | 49 | 50 | # -- Options for HTML output ------------------------------------------------- 51 | 52 | # The theme to use for HTML and HTML Help pages. See the documentation for 53 | # a list of builtin themes. 54 | # 55 | #html_theme = 'alabaster' 56 | html_theme = 'sphinx_rtd_theme' 57 | 58 | # Add any paths that contain custom static files (such as style sheets) here, 59 | # relative to this directory. They are copied after the builtin static files, 60 | # so a file named "default.css" will overwrite the builtin "default.css". 61 | html_static_path = ['_static'] 62 | 63 | # Make sure the target is unique 64 | autosectionlabel_prefix_document = True 65 | 66 | autodoc_default_options = { 67 | 'special-members': '__init__', 68 | } 69 | 70 | # -- Options for breathe ------------------------------------------------- 71 | #breathe_default_project = "losc" 72 | -------------------------------------------------------------------------------- /docs_source/sphinx/index.rst: -------------------------------------------------------------------------------- 1 | .. Localized Orbital Scaling Correction (LOSC) Library documentation master file, created by 2 | sphinx-quickstart on Thu Feb 25 13:14:06 2021. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ============================================ 7 | Localized Orbital Scaling Correction Library 8 | ============================================ 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | :caption: Contents 13 | 14 | introduction.rst 15 | installation.rst 16 | LOSC C++ library 17 | LOSC C library 18 | LOSC Python library 19 | Using LOSC library in psi4 20 | -------------------------------------------------------------------------------- /docs_source/sphinx/installation.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Installation 3 | ============ 4 | 5 | .. note:: Currently, the library can only be used in linux platform. 6 | 7 | ---------------------- 8 | Dependencies and tools 9 | ---------------------- 10 | 11 | - To build the C++/C parts of the LOSC library, following tools and dependencies 12 | are necessary: 13 | 14 | - C++ and C compilers (C++11 compliant) 15 | - `Eigen3 library `_ 16 | - `CMake `_ 17 | - `Openmp `_ 18 | - System utilities: GNU make, GNU install, 19 | 20 | - For the Python parts of the LOSC library, namely the 21 | :ref:`py_losc ` and 22 | :ref:`psi4_losc ` modules, 23 | there is no need to compile. However, following dependencies are needed 24 | at the running time: 25 | 26 | - `Python interpreter (3.7) `_ 27 | - `Numpy `_ 28 | - `The psi4 package `_ for using the 29 | ``psi4_losc`` module. 30 | 31 | - There is no need to build the documentation by yourself. You can find the 32 | `online documentation `_. However, if you 33 | insist to generate the documentation that is corresponding to your local 34 | version of the source code, you need the following dependencies and tools: 35 | 36 | - `sphinx `_: python documentation 37 | generator. 38 | - `doxygen `_: C/C++ documentation 39 | generator. 40 | 41 | ---------------------------- 42 | Compile from the source code 43 | ---------------------------- 44 | 45 | #. you can obtain the source code from `the github repository 46 | `_ via ``git clone``: 47 | 48 | .. code-block:: bash 49 | 50 | >>> git clone https://github.com/Yang-Laboratory/losc 51 | 52 | Doing so requires you to have ``git`` installed in your system. If you do 53 | not have access to ``git``, you can download the archive of the source 54 | code from the `the github repository `_, 55 | and extract the source manually. 56 | 57 | #. Navigate to the top level directory of the source code 58 | ``{top-level-losc-dir}``. It is suggested to separate the building files 59 | to the source files with creating a build directory ``{build_dir}``. 60 | Then run ``cmake`` to configure the building process. 61 | 62 | .. code-block:: bash 63 | 64 | >>> cd {top-level-losc-dir} 65 | >>> mkdir {build_dir} 66 | >>> cd {build_dir} 67 | >>> cmake {top-level-losc-dir} 68 | 69 | You can configure ``cmake`` with following options: 70 | 71 | - ``DCMAKE_C_COMPILER``: The executable path for C compiler 72 | - ``DCMAKE_CXX_COMPILER``: The executable path for C++ compiler 73 | - ``DCMAKE_INSTALL_PREFIX``: The prefix path for installing the library. 74 | Default to ``/usr/local``. 75 | - ``DOPENMP``: Enable ``openmp`` for parallel threading or not. 76 | Default to on. 77 | - ``DBUILD_TEST``: Build the test or not. Default to off. 78 | - ``DBUILD_DOC``: Build the documentation or not. Default to off. 79 | 80 | #. Invoke ``make`` to build and install. 81 | 82 | .. code-block:: bash 83 | 84 | >>> make 85 | >>> make install # installing is optional. 86 | 87 | or invoke``make`` in parallel with multiple processors. 88 | 89 | .. code-block:: bash 90 | 91 | >>> make -j {number-of-processors} 92 | 93 | **If all you need is the C/C++ parts of the LOSC library, you are okay to 94 | stop here. If you want to use the Python interface or the LOSC library 95 | in psi4, please continue.** 96 | 97 | #. Configure running time for Python modules (``py_losc`` and ``psi4_losc``). 98 | 99 | Append the path of ``py_losc`` and ``psi4_losc`` module to the ``PYTHONPATH`` 100 | environment variable in your ``~/.zshrc`` or ``~/.bashrc`` file. This is to 101 | enable the Python interpreter to locate ``py_losc`` and ``psi4_losc`` modules 102 | and import them successfully at running time. 103 | 104 | If you installed the LOSC library: 105 | 106 | .. code-block:: bash 107 | 108 | export PYTHONPATH=${PYTHONPATH}:{DCMAKE_INSTALL_PREFIX}/liblosc 109 | 110 | If you only build the LOSC library and not install it: 111 | 112 | .. code-block:: bash 113 | 114 | export PYTHONPATH=${PYTHONPATH}:{build_dir}/src 115 | 116 | #. Running tests to verify the compilation/installing is optional. 117 | 118 | - To run tests for ``losc`` C++ library, remember to build tests for 119 | ``losc`` first with ``DBUILD_TEST=On``. Then run the executable losc test 120 | file. 121 | 122 | .. code-block:: bash 123 | 124 | >>> {build_dir}/tests/losc/losc_test 125 | 126 | - To run tests for ``psi4_losc`` Python module, do the following. 127 | 128 | .. code-block:: bash 129 | 130 | >>> cd {top-level-losc-dir}/tests/psi4_losc 131 | >>> python3 -m unittest test_scf_losc.py --verbose 132 | 133 | - There are no tests for ``py_losc`` Python module. 134 | 135 | -------------------------- 136 | Uninstall the LOSC library 137 | -------------------------- 138 | 139 | To uninstall the LOSC library, remove the whole installed directory of 140 | LOSC. 141 | 142 | .. code-block:: bash 143 | 144 | >>> rm {DCMAKE_INSTALL_PREFIX}/liblosc 145 | -------------------------------------------------------------------------------- /docs_source/sphinx/introduction.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Introduction 3 | ============ 4 | 5 | ------------------------ 6 | What is the LOSC method? 7 | ------------------------ 8 | 9 | The localized orbital scaling correction (LOSC) is a newly developed method in 10 | density functional theory (DFT) to eliminate the delocalization error (DE) 11 | of many conventional density functional approximations (DFAs). Bascally, 12 | the LOSC method involves a set of localized orbitals (LOs) to construct 13 | the local occupation number, the LOSC curvature matrix and the LOSC corrections. 14 | The references of LOSC that describes the detailed methodology are listed 15 | :ref:`here `. 16 | 17 | ----------------------------- 18 | What is the LOSC library for? 19 | ----------------------------- 20 | The LOSC library is developed for two goals: 21 | 22 | - It provides sub-libraries with compatible interfaces to several popular 23 | programming languages in quantum chemistry, including 24 | :ref:`C `, :ref:`C++ ` and 25 | :ref:`Python `, for the developers who would 26 | be interested to implement LOSC method in their favorite quantum chemistry 27 | packages. These sub-libraries provide the functionalities to perform the 28 | essential calculations of the LOSC method, such as constructing the LOs, 29 | LOSC curvature matrix, and LOSC corrections. 30 | 31 | - It provides the implementation of LOSC method in an open-source quantum 32 | chemistry package, `psi4 `_, with the Python interface. 33 | If you are a user of pis4, you can directly use this library with psi4 34 | to perform LOSC calculations. 35 | See :ref:`this section `. 36 | 37 | ------------------ 38 | References of LOSC 39 | ------------------ 40 | 41 | .. [#losc1] Li, C.; Zheng, X.; Su, N. Q.; Yang, W. Localized Orbital Scaling 42 | Correction for System- atic Elimination of Delocalization Error in 43 | Density Functional Approximations. 44 | `Natl. Sci. Rev. 2018, 5, 203−215. 203-215. 45 | `_ 46 | 47 | .. [#losc2] Su, N. Q.; Mahler, A.; Yang, W. Preserving Symmetry and 48 | Degeneracy in the Localized Orbital Scaling Correction Approach. J. 49 | `Phys. Chem. Lett. 2020, 11, 1528−1535. 50 | `_ 51 | 52 | .. [#scf-losc] Mei, Y.; Chen, Z.; Yang, W. 53 | Self-Consistent Calculation of the Localized Orbital Scaling Correction 54 | for Correct Electron Densities and Energy-Level Alignments in Density 55 | Functional Theory. 56 | `J. Phys. Chem. Lett. 2020, 11, 23, 10269–10277. 57 | `_ 58 | -------------------------------------------------------------------------------- /docs_source/sphinx/losc.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | LOSC C++ library 3 | ================ 4 | 5 | Introduction 6 | ------------ 7 | 8 | The LOSC library provides a C++ interface to perform calculations of LOSC, 9 | including the construction of LOSC curvature matrix, LOSC localization, 10 | local occupation number and LOSC corrections. 11 | 12 | The provided C++ interface (C++ header files) includes 13 | 14 | ================================== ====================================== 15 | Header Description 16 | ================================== ====================================== 17 | ```` for the LOSC curvature matrix. 18 | ```` for the LOSC localization. 19 | ```` for the LOSC local occupation. 20 | ```` for the LOSC corrections. 21 | ```` for the exceptions that may be thrown 22 | in LOSC library. 23 | ```` for the declarations of matrix used 24 | in LOSC library. 25 | ```` A convenient header that includes 26 | everything you need. 27 | ================================== ====================================== 28 | 29 | In order to use the C++ interface of the LOSC library, following the 30 | :ref:`steps of installation `. Then all you 31 | need to do is to include the corresponding headers in your project 32 | to use the LOSC C++ library. 33 | 34 | Data Structure 35 | -------------- 36 | The main data structure in the LOSC C++ library is the representation of 37 | matrix/vector objects. In the LOSC C++ library, we use the 38 | popular `Eigen library `_, 39 | which lets us achieve the manipulation of matrices and vectors easily. 40 | Particularly, we use ``Eigen::Matrix`` to represent matrices, and 41 | ``Eigen::Vector`` to represent vectors. 42 | 43 | Being different to the default behavior in ``Eigen`` that the storage of matrix 44 | is column-wise (Fortran-style), the storage of matrix in the LOSC C++ library 45 | is row-wise (C-style). To avoid declaring the row-wise ``Eigen::Matrix`` 46 | in a cumbersome way being like 47 | 48 | .. code-block:: C++ 49 | 50 | Eigen::Matrix; 51 | 52 | an alias ``LOSCMatrix`` is defined in ```` as 53 | 54 | .. code-block:: C++ 55 | 56 | using LOSCMatrix = Eigen::Matrix; 57 | 58 | There is a similar alias ``LOSCVector`` for the vector objects. For other 59 | alias of ``Eigen`` types that are used the LOSC C++ library, please 60 | refer to ````. 61 | 62 | Detailed References for the API 63 | ------------------------------- 64 | 65 | Please refer `this section <./doxygen/losc/html/index.html>`_ for the full 66 | documentation of C++ interface of the LOSC library. 67 | -------------------------------------------------------------------------------- /docs_source/sphinx/psi4_api_ref__psi4_losc.rst: -------------------------------------------------------------------------------- 1 | **Full list of psi4 Python API used in psi4_losc module** 2 | ********************************************************* 3 | 4 | .. Warning:: The list may not be complete. The list is for the package 5 | developers to show the interaction between ``psi4_losc`` module and 6 | ``psi4`` Python API. 7 | 8 | - psi4.driver 9 | 10 | - `driver.p4util.OptionsState 11 | `_ 12 | 13 | - OptionsState.restore() 14 | 15 | - driver.scf_wavefunction_factory() 16 | 17 | - `psi4.core.clean() 18 | `_ 19 | - `psi4.core.get_active_molecule() 20 | `_ 21 | - `psi4.core.get_option() 22 | `_ 23 | - `psi4.core.set_local_option() 24 | `_ 25 | 26 | - `psi4.core.BasisSet 27 | `_ 28 | 29 | - `nbf() 30 | `_ 31 | - `build() 32 | `_ 33 | 34 | - `psi4.core.MintsHelper 35 | `_ 36 | 37 | - `ao_dipole() 38 | `_ 39 | 40 | - `psi4.core.Wavefunction 41 | `_ 42 | 43 | - `molecule() 44 | `_ 45 | - `S() 46 | `_ 47 | - `Ca() 48 | `_ 49 | - `Cb() 50 | `_ 51 | - `Fa() 52 | `_ 53 | - `Fb() 54 | `_ 55 | - `Da() 56 | `_ 57 | - `Db() 58 | `_ 59 | - `nalphe() 60 | `_ 61 | - `nbeta() 62 | `_ 63 | - `epsilon_a() 64 | `_ 65 | - `epsilon_b() 66 | `_ 67 | - `energy() 68 | `_ 69 | - `basisset() 70 | `_ 71 | - `same_a_b_orbs() 72 | `_ 73 | - `same_a_b_dens() 74 | `_ 75 | - `build() 76 | `_ 77 | 78 | - `psi4.core.HF 79 | `_ 80 | 81 | - `functional() 82 | `_ 83 | 84 | - `psi4.core.SuperFunctional 85 | `_ 86 | 87 | - `is_x_lrc() 88 | `_ 89 | - `is_c_hybrid() 90 | `_ 91 | - `is_meta() 92 | `_ 93 | 94 | - `psi4.core.Molecule 95 | `_ 96 | 97 | - `schoenflies_symbol() 98 | `_ 99 | - `print_out() 100 | `_ 101 | - `nuclear_repulsion_energy() 102 | `_ 103 | -------------------------------------------------------------------------------- /docs_source/sphinx/py_losc.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | LOSC Python library 3 | =================== 4 | 5 | ------------ 6 | Introduction 7 | ------------ 8 | ``py_losc`` is the Python module that provides the Python interface to do 9 | calculations of LOSC. It wraps the 10 | :ref:`LOSC C++ library ` with the help of 11 | `pybind11 library `_. 12 | The functionalities provided in ``py_losc`` library are similar to the 13 | :ref:`LOSC C++ library `. 14 | 15 | ------------ 16 | Basic Guide 17 | ------------ 18 | 19 | To use Python interface for the LOSC library, all you need to do is 20 | ``import py_losc``. 21 | 22 | - To construct LOSC curvature matrix, 23 | see :ref:`this section `. 24 | - To perform LOSC localization, 25 | see :ref:`this section `. 26 | - To calculate LOSC corrections, 27 | see :ref:`this section `. 28 | 29 | To implement post-SCF-LOSC and SCF-LOSC calculations in Python with 30 | the ``py_losc`` module, please refer to :ref:`this section 31 | `, which demonstrates a real 32 | example of using ``py_losc`` in psi4 package. 33 | 34 | ------------------------------- 35 | Detailed References for the API 36 | ------------------------------- 37 | 38 | .. automodule:: py_losc 39 | 40 | DFA Representation in LOSC Library 41 | ********************************** 42 | .. autoclass:: py_losc.DFAInfo 43 | :members: 44 | :inherited-members: 45 | 46 | LOSC Curvature 47 | ************** 48 | .. autoclass:: py_losc.CurvatureV1 49 | :members: 50 | :inherited-members: 51 | .. autoclass:: py_losc.CurvatureV2 52 | :members: 53 | :inherited-members: 54 | 55 | 56 | LOSC Localization 57 | ***************** 58 | .. autoclass:: py_losc.LocalizerV2 59 | :members: 60 | :inherited-members: 61 | 62 | LOSC Local Occupation 63 | ********************* 64 | .. autofunction:: py_losc.local_occupation 65 | 66 | LOSC Corrections 67 | **************** 68 | .. autofunction:: py_losc.ao_hamiltonian_correction 69 | .. autofunction:: py_losc.energy_correction 70 | .. autofunction:: py_losc.orbital_energy_post_scf 71 | -------------------------------------------------------------------------------- /include/c_losc/correction.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief The C interface for LOSC corrections. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_C_LOSC_CORRECTION_H_ 7 | #define _LOSC_INCLUDE_C_LOSC_CORRECTION_H_ 8 | 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | * @class __param__Curvature 18 | * @param [in] Curvature LOSC curvature matrix with dimension of `[nlo, nlo]`. 19 | */ 20 | 21 | /** 22 | * @class __param__LocalOcc 23 | * @param [in] LocalOcc Local occupation matrix with dimension of `[nlo, nlo]`. 24 | */ 25 | 26 | /** 27 | * @class __param__C_lo 28 | * @param [in] C_lo LOs coefficient matrix under AOs with dimension of 29 | * `[nbasis, nlo]`. The `i`-th column in `C_lo` matrix is the `i`-th LO. 30 | */ 31 | 32 | /** 33 | * @brief Calculate LOSC effective Hamiltonian under AO basis. 34 | * @details The LOSC effective Hamiltonian is constructed with LOs fixed. The 35 | * expression of the effective Hamiltonian is shown as Eq. S25 in the 36 | * supporting information of the original LOSC paper 37 | * (https://doi.org/10.1093/nsr/nwx111). This effective Hamiltonian is exact 38 | * in the developed version of SCF-LOSC (self-consistent LOSC). See reference 39 | * (J. Phys. Chem. Lett. 2020, 11, 23, 10269-10277) for more details about 40 | * how to perform reliable SCF-LOSC calculations. 41 | * @param [in] S AO overlap matrix with dimension [nbasis, nbasis]. 42 | * @copydoc __param__C_lo 43 | * @copydoc __param__Curvature 44 | * @copydoc __param__LocalOcc 45 | * @return Create a LOSC effective Hamiltonian matrix with dimension 46 | * `[nbasis, nbasis]` and return the matrix pointer. 47 | * @see LoscCurvatureBase.kappa: Obtain the curvature matrix. 48 | * @see losc_local_occupation(): Obtain the local occupation matrix. 49 | * @note Make sure all the input matrices are corrresponding to the same spin. 50 | */ 51 | losc_matrix *losc_ao_hamiltonian_correction(const losc_matrix *S, 52 | const losc_matrix *C_lo, 53 | const losc_matrix *Curvature, 54 | const losc_matrix *LocalOcc); 55 | 56 | /** 57 | * @brief Calculate the total energy correction from LOSC. 58 | * @details This is just the energy correction from LOSC, NOT the total energy 59 | * of LOSC-DFA. Total energy of LOSC-DFA is: ``E_losc_dfa = E_dfa + E_losc``. 60 | * @copydoc __param__Curvature 61 | * @copydoc __param__LocalOcc 62 | * @return The total energy correction from LOSC. 63 | * @see LoscCurvatureBase.kappa: obtain the LOSC curvature matrix. 64 | * @see losc_local_occupation(): obtain the LOSC local occupation matrix. 65 | */ 66 | double energy_correction(const losc_matrix *Curvature, 67 | const losc_matrix *LocalOcc); 68 | 69 | /** 70 | * @brief Calculate corrected orbital energy from LOSC in a post-SCF approach. 71 | * @details This function gives the final orbital energies WITH the correction 72 | * from LOSC. Note the difference to the function energy_correction() that only 73 | * calculates the energy correction. The corrected orbital energies are the 74 | * expectation values of converged DFA's COs on the LOSC-DFA Hamiltonian, 75 | * that is, 76 | * \f[ 77 | * \epsilon_i = \langle \psi_i | H_{\rm{dfa}} + H_{\rm{losc}} | \psi_i \rangle. 78 | * \f] 79 | * @param [in] H_dfa The DFA Hamiltonian under AOs with dimension of 80 | * `[nbasis, nbasis]`. 81 | * @param [in] H_losc The LOSC effective Hamiltonian under AOs with dimension 82 | * of `[nbasis, nbasis]`. 83 | * @param [in] C_co The coefficient matrix of converged DFA COs under AOs 84 | * with dimension of `[nbasis, n]` (`n <= nbasis`, which is the number of COs). 85 | * You can choose whatever number of COs you want. 86 | * @return Create an array of the corrected orbital energies from LOSC with 87 | * size of `n` and return the pointer. The order of orbital energies match the 88 | * order of input COs (order of columns in `C_co` matrix). 89 | * @see losc_ao_hamiltonian_correction(): obtain the LOSC effective Hamiltonian 90 | * under AOs. 91 | * @note This function only calculates the orbital energies for the single spin 92 | * associated with the input matrices. 93 | * @note This function is just one of the ways to construct the LOSC corrected 94 | * orbital energies in the post-SCF LOSC calculations. It is the way we used to 95 | * produce results in the published paper for the post-SCF LOSC calculations. 96 | * Besides this way, there are another two ways to calculate corrected orbital 97 | * energies: (1) diagonalize the corrected LOSC-DFA Hamiltonian; 98 | * (2) follow Eq. 11 of the original paper of LOSC to calculate the corrections 99 | * to orbital energies. These three ways usually produce very similar results. 100 | */ 101 | double *orbital_energy_post_scf(const losc_matrix *H_dfa, 102 | const losc_matrix *H_losc, 103 | const losc_matrix *C_co); 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /include/c_losc/local_occupation.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief The C interface for LOSC local occupation number. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_C_LOSC_LOCAL_OCCUPATION_H_ 7 | #define _LOSC_INCLUDE_C_LOSC_LOCAL_OCCUPATION_H_ 8 | 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | * @brief Create the local occupation matrix. 18 | * @param [in] C_lo: LO coefficient matrix with dimension `[nbasis, nlo]`. 19 | * @param [in] S: AO overlap matrix with dimension `[nbasis, nbasis]`. 20 | * @param [in] D: Spin density matrix under AO with dimension 21 | * `[nbasis, nbasis]`. 22 | * @return Create a local occupation matrix with dimension `[nlo, nlo]` and 23 | * return the pointer. 24 | * @see LoscLocalizerBase.lo: Obtain the LOs' coefficient matrix. 25 | * @note The local occupation matrix is defined as 26 | * \f$\displaystyle \lambda_{ij} = \langle \phi_i|\rho|\phi_j \rangle \f$, 27 | * where \f$ \lambda_{ij} \f$ is the local occupation matrix 28 | * element, \f$ \phi_i \f$ and \f$ \phi_j \f$ are the i-th and j-th localized 29 | * orbital and \f$ \rho \f$ is the spin density operator. 30 | * In matrix form, local occupation matrix \f$ L \f$ is expressed as 31 | * \f$ L = C_{\rm{LO}}^T S D S C_{\rm{LO}} \f$. 32 | */ 33 | losc_matrix *losc_local_occupation(const losc_matrix *C_lo, 34 | const losc_matrix *S, const losc_matrix *D); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/c_losc/losc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C interface for localized orbital scaling correction (LOSC) library. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_C_LOSC_LOSC_H_ 7 | #define _LOSC_INCLUDE_C_LOSC_LOSC_H_ 8 | 9 | #include // This brings the interface of matrix. 10 | #include // This brings the interface of corrections. 11 | #include // This brings the interface of curvature. 12 | #include // This brings the interface of local occupation. 13 | #include // This brings the interface of localization. 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/c_losc/matrix.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief The C interface of matrix used in LOSC. 4 | * @details The struct losc_matrix is used to represent matrix object and 5 | * shared between the C code and C++ LOSC library. The C users only need 6 | * the interface as provided in this header file to use struct losc_matrix. 7 | * The implementation of struct losc_matrix is hid. 8 | */ 9 | 10 | #ifndef _LOSC_INCLUDE_C_LOSC_MATRIX_H_ 11 | #define _LOSC_INCLUDE_C_LOSC_MATRIX_H_ 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** 19 | * @brief losc_matrix 20 | * @note The complete definition of losc_matrix is hid. 21 | */ 22 | typedef struct losc_matrix losc_matirx; 23 | 24 | /** 25 | * @brief Create a LOSC matrix object with data allocated. 26 | * @param [in] row number of rows. 27 | * @param [in] col number of columns. 28 | * @return Create a matrix and return the pointer. 29 | */ 30 | losc_matrix *losc_matrix_create(size_t row, size_t col); 31 | 32 | /** 33 | * @brief Create a LOSC matrix object with data owned externally. 34 | * @param [in] row: number of rows. 35 | * @param [in] col: number of columns. 36 | * @param [in] data: `data` points to an array which represents a matrix with 37 | * dimension of `[row, col]`. The matrix is assumed to be stored in row-major. 38 | * The size of the array is assumed to be at least `row x col`. 39 | * @return Create a matrix and return the pointer. 40 | * @note This created matrix does not own the data. 41 | */ 42 | losc_matrix *losc_matrix_create_from_data(size_t row, size_t col, double *data); 43 | 44 | /** 45 | * @brief Free the losc_matrix. 46 | * @param [in, out] ptr a pointer with type `losc_matrix *`. At exit, 47 | * `ptr` is set to null. 48 | */ 49 | #define losc_matrix_free(ptr) _losc_matrix_free(&(ptr)) 50 | void _losc_matrix_free(losc_matrix **pptr_m); 51 | 52 | /** 53 | * @brief Return the pointer that points to the head of matrix data. 54 | * @param [in] m a losc_matrix pointer. 55 | */ 56 | double *losc_matrix_data(losc_matrix *m); 57 | 58 | /** 59 | * @brief Return the const pointer that points to the head of matrix data. 60 | * @param [in] m a const losc_matrix pointer. 61 | */ 62 | const double *losc_matrix_data_const(const losc_matrix *m); 63 | 64 | /** 65 | * @brief Return the number of rows. 66 | */ 67 | size_t losc_matrix_rows(const losc_matrix *m); 68 | 69 | /** 70 | * @brief Return the number of columns. 71 | */ 72 | size_t losc_matrix_cols(const losc_matrix *m); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /include/losc/eigen_def.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A collection of alias to ``Eigen`` types that used in LOSC. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_LOSC_EIGEN_DEF_HPP_ 7 | #define _LOSC_INCLUDE_LOSC_EIGEN_DEF_HPP_ 8 | 9 | #include 10 | 11 | namespace losc { 12 | 13 | using Eigen::Map; 14 | using Eigen::Ref; 15 | 16 | /** 17 | * @brief Matrix object used in LOSC. 18 | * @note The storage order is row-wise (C-style), which is opposite to the 19 | * ``Eigen`` default behavior. 20 | */ 21 | using LOSCMatrix = 22 | Eigen::Matrix; 23 | 24 | /** 25 | * @brief Vector object used in LOSC. 26 | */ 27 | using LOSCVector = Eigen::VectorXd; 28 | 29 | /** 30 | * @brief Constatnt reference to a constant LOSCMatrix object 31 | */ 32 | using ConstRefMat = const Ref; 33 | 34 | /** 35 | * @brief Constatnt reference to a constant LOSCVector object 36 | */ 37 | using ConstRefVec = const Ref; 38 | 39 | /** 40 | * @brief Reference to a constant LOSCMatrix object 41 | */ 42 | using RefConstMat = Ref; 43 | 44 | /** 45 | * @brief Reference to a constant LOSCVector object 46 | */ 47 | using RefConstVec = Ref; 48 | 49 | /** 50 | * @brief Reference to a LOSCMatrix object 51 | */ 52 | using RefMat = Ref; 53 | 54 | /** 55 | * @brief Reference to a LOSCVector object 56 | */ 57 | using RefVec = Ref; 58 | 59 | /** 60 | * @brief Constatnt map to a constant LOSCMatrix object 61 | */ 62 | using ConstMapMat = const Map; 63 | 64 | /** 65 | * @brief Constatnt map to a constant LOSCVetor object 66 | */ 67 | using ConstMapVec = const Map; 68 | 69 | /** 70 | * @brief Map to a constant LOSCMatrix object 71 | */ 72 | using MapConstMat = Map; 73 | 74 | /** 75 | * @brief Map to a constant LOSCVetor object 76 | */ 77 | using MapConstVec = Map; 78 | 79 | /** 80 | * @brief Map to a LOSCMatrix object 81 | */ 82 | using MapMat = Map; 83 | 84 | /** 85 | * @brief Map to a LOSCVetor object 86 | */ 87 | using MapVec = Map; 88 | 89 | } // namespace losc 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /include/losc/exception.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C++ interface for the LOSC exceptions. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_LOSC_EXCEPTION_HPP_ 7 | #define _LOSC_INCLUDE_LOSC_EXCEPTION_HPP_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace losc { 14 | 15 | /** 16 | * @brief namespace for losc exceptions. 17 | */ 18 | namespace exception { 19 | 20 | using losc::ConstRefMat; 21 | using losc::ConstRefVec; 22 | using losc::RefMat; 23 | using losc::RefVec; 24 | using std::string; 25 | using std::stringstream; 26 | 27 | /** 28 | * @brief The base exception in LOSC 29 | */ 30 | class LoscException : public std::runtime_error { 31 | private: 32 | void make_message(const char *msg); 33 | 34 | protected: 35 | string msg_; 36 | 37 | public: 38 | /** 39 | * @brief Constructor of LoscException. 40 | * @param [in] msg the description of error. 41 | */ 42 | LoscException(const std::string &msg) : std::runtime_error(msg) 43 | { 44 | make_message(msg.c_str()); 45 | } 46 | 47 | /** 48 | * @brief Deconstructor of LoscException. 49 | */ 50 | ~LoscException() {} 51 | 52 | const char *what() const noexcept override { return msg_.c_str(); } 53 | }; 54 | 55 | /** 56 | * @brief The exception related to dimension error in LOSC 57 | */ 58 | class DimensionError : public LoscException { 59 | public: 60 | /** 61 | * @brief Constructor of DimensionError related to a matrix. 62 | * @param [in] A a LOSC matrix. 63 | * @param [in] expected_row the expected row number of `A`. 64 | * @param [in] expected_col the expected column number of `A`. 65 | * @param [in] msg the description of error. 66 | */ 67 | DimensionError(ConstRefMat &A, size_t expected_row, size_t expected_col, 68 | const string &msg); 69 | /** 70 | * @brief Constructor of DimensionError with a general message. 71 | * @param [in] msg the description of error. 72 | */ 73 | DimensionError(const string &msg); 74 | 75 | /** 76 | * @brief Deconstructor of DimensionError. 77 | */ 78 | ~DimensionError() {} 79 | }; 80 | 81 | } // namespace exception 82 | } // namespace losc 83 | #endif // _LOSC_SRC_EXCEPTION_H_ 84 | -------------------------------------------------------------------------------- /include/losc/local_occupation.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C++ interface for the local occupation matrix within LOSC. 4 | */ 5 | 6 | #ifndef _LOSC_INCLUDE_LOSC_LOCAL_OCCUPATION_HPP_ 7 | #define _LOSC_INCLUDE_LOSC_LOCAL_OCCUPATION_HPP_ 8 | 9 | #include 10 | 11 | namespace losc { 12 | 13 | /** 14 | * @class __param__LocalOcc 15 | * @param [in] LocalOcc LOSC local occupation matrix with dimension of 16 | * `[nlo, nlo]`. 17 | */ 18 | 19 | /** 20 | * @class __param__local_occupation 21 | * @copydoc __param__C_lo 22 | * @param [in] S: AO overlap matrix with dimension `[nbasis, nbasis]`. 23 | * @param [in] D: Spin density matrix under AO with dimension 24 | * `[nbasis, nbasis]`. 25 | */ 26 | 27 | /** 28 | * @class __see__note__local_occupation 29 | * @see losc::LocalizerV2::lo(): Obtain the LOs' coefficient matrix. 30 | * @note The local occupation matrix is defined as 31 | * \f$\displaystyle \lambda_{ij} = \langle \phi_i|\rho|\phi_j \rangle \f$, 32 | * where \f$ \lambda_{ij} \f$ is the local occupation matrix 33 | * element, \f$ \phi_i \f$ and \f$ \phi_j \f$ are the i-th and j-th localized 34 | * orbital and \f$ \rho \f$ is the spin density operator. 35 | * In matrix form, local occupation matrix \f$ L \f$ is expressed as 36 | * \f$ L = C_{\rm{LO}}^T S D S C_{\rm{LO}} \f$. 37 | */ 38 | 39 | /** 40 | * @brief Calculate the local occupation matrix. 41 | * @copydoc __param__local_occupation 42 | * @return The local occupation matrix with dimension `[nlo, nlo]`. 43 | * @copydoc __see__note__local_occupation 44 | */ 45 | LOSCMatrix local_occupation(ConstRefMat &C_lo, ConstRefMat &S, ConstRefMat &D); 46 | 47 | /** 48 | * @brief C interface to calculate the local occupation matrix. 49 | * @copydoc __param__local_occupation 50 | * @param [in, out] LocalOcc A matrix with dimension `[nlo, nlo]`. At entrance, 51 | * its data is ignored. At exit, it stores the local occupation matrix. 52 | * @copydoc __see__note__local_occupation 53 | */ 54 | void C_API_local_occupation(ConstRefMat &C_lo, ConstRefMat &S, ConstRefMat &D, 55 | RefMat LocalOcc); 56 | } // namespace losc 57 | #endif // _LOSC_SRC_LOCAL_OCCUPATION_H_ 58 | -------------------------------------------------------------------------------- /include/losc/losc.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C++ interface for the localized orbital scaling correction (LOSC) 4 | * library. 5 | */ 6 | 7 | #ifndef _LOSC_INCLUDE_LOSC_LOSC_HPP_ 8 | #define _LOSC_INCLUDE_LOSC_LOSC_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # C++ losc library 2 | add_subdirectory(losc) 3 | 4 | # C losc library 5 | add_subdirectory(c_losc) 6 | 7 | # python losc library 8 | add_subdirectory(py_losc) 9 | 10 | # psi4 losc library 11 | add_subdirectory(psi4_losc) 12 | 13 | # pyscf losc library 14 | add_subdirectory(pyscf_losc) 15 | 16 | -------------------------------------------------------------------------------- /src/c_losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME c_losc) 2 | project(${PROJECT_NAME} C CXX) 3 | 4 | # sources 5 | file(GLOB SOURCES "*.cpp") 6 | set(C_LOSC_PUBLIC_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") 7 | 8 | # ==> build c_losc library <== 9 | add_library( 10 | ${PROJECT_NAME} SHARED 11 | ${SOURCES}) 12 | 13 | target_link_libraries( 14 | ${PROJECT_NAME} 15 | PUBLIC 16 | Eigen3::Eigen 17 | ${PROJECT_LOSC}) 18 | 19 | target_include_directories( 20 | ${PROJECT_NAME} 21 | PUBLIC 22 | ${C_LOSC_PUBLIC_INCLUDE_DIR}) 23 | 24 | # ==> install losc library <== 25 | install(TARGETS ${PROJECT_NAME} DESTINATION lib) 26 | install(DIRECTORY "${C_LOSC_PUBLIC_INCLUDE_DIR}/c_losc" DESTINATION include) 27 | -------------------------------------------------------------------------------- /src/c_losc/correction.cpp: -------------------------------------------------------------------------------- 1 | #include "matrix_impl.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | extern "C" { 7 | 8 | losc_matrix *losc_ao_hamiltonian_correction(const losc_matrix *S, 9 | const losc_matrix *C_lo, 10 | const losc_matrix *Curvature, 11 | const losc_matrix *LocalOcc) 12 | { 13 | const size_t nbasis = S->col_; 14 | losc_matrix *H_losc = losc_matrix_create(nbasis, nbasis); 15 | losc::C_API_ao_hamiltonian_correction( 16 | losc_matrix_to_eigen_const(S), losc_matrix_to_eigen_const(C_lo), 17 | losc_matrix_to_eigen_const(Curvature), 18 | losc_matrix_to_eigen_const(LocalOcc), losc_matrix_to_eigen(H_losc)); 19 | return H_losc; 20 | } 21 | 22 | double energy_correction(const losc_matrix *Curvature, 23 | const losc_matrix *LocalOcc) 24 | { 25 | return losc::energy_correction(losc_matrix_to_eigen_const(Curvature), 26 | losc_matrix_to_eigen_const(LocalOcc)); 27 | } 28 | 29 | double *orbital_energy_post_scf(const losc_matrix *H_dfa, 30 | const losc_matrix *H_losc, 31 | const losc_matrix *C_co) 32 | { 33 | const size_t n = C_co->col_; 34 | double *eig = (double *)calloc(n, sizeof(double)); 35 | losc::C_API_orbital_energy_post_scf(losc_matrix_to_eigen_const(H_dfa), 36 | losc_matrix_to_eigen_const(H_losc), 37 | losc_matrix_to_eigen_const(C_co), eig); 38 | return eig; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/c_losc/local_occupation.cpp: -------------------------------------------------------------------------------- 1 | #include "matrix_impl.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | extern "C" { 7 | 8 | losc_matrix *losc_local_occupation(const losc_matrix *C_lo, 9 | const losc_matrix *S, const losc_matrix *D) 10 | { 11 | const size_t nlo = C_lo->col_; 12 | losc_matrix *LocalOcc = losc_matrix_create(nlo, nlo); 13 | losc::C_API_local_occupation( 14 | losc_matrix_to_eigen_const(C_lo), losc_matrix_to_eigen_const(S), 15 | losc_matrix_to_eigen_const(D), losc_matrix_to_eigen(LocalOcc)); 16 | return LocalOcc; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/c_losc/localization.cpp: -------------------------------------------------------------------------------- 1 | #include "matrix_impl.hpp" 2 | #include 3 | #include 4 | 5 | extern "C" { 6 | 7 | //********************************************** 8 | // ==> Binding `losc::LocalizerBase` methods. 9 | //********************************************** 10 | 11 | static void losc_localizer_base_set_max_iter(const LoscLocalizerBase *self, 12 | size_t max_iter) 13 | { 14 | auto base = reinterpret_cast(self->_p_base); 15 | base->set_max_iter(max_iter); 16 | } 17 | 18 | static void losc_localizer_base_set_convergence(const LoscLocalizerBase *self, 19 | double tol) 20 | { 21 | auto base = reinterpret_cast(self->_p_base); 22 | base->set_convergence(tol); 23 | } 24 | 25 | static void 26 | losc_localizer_base_set_random_permutation(const LoscLocalizerBase *self, 27 | bool flag) 28 | { 29 | auto base = reinterpret_cast(self->_p_base); 30 | base->set_random_permutation(flag); 31 | } 32 | 33 | static void losc_localizer_base_lo_U(const LoscLocalizerBase *self, 34 | losc_matrix *L, losc_matrix *U) 35 | { 36 | auto base = reinterpret_cast(self->_p_base); 37 | base->C_API_lo_U(losc_matrix_to_eigen(L), losc_matrix_to_eigen(U)); 38 | } 39 | 40 | /** 41 | * Create a `struct LoscLocalizerBase` and assign all its function pointers 42 | */ 43 | static LoscLocalizerBase * 44 | create_losc_localizer_base(losc::LocalizerBase *_p_base) 45 | { 46 | auto p_base = new LoscLocalizerBase; 47 | p_base->_p_base = reinterpret_cast<_LocalizerBase *>(_p_base); 48 | p_base->set_max_iter = losc_localizer_base_set_max_iter; 49 | p_base->set_convergence = losc_localizer_base_set_convergence; 50 | p_base->set_random_permutation = losc_localizer_base_set_random_permutation; 51 | p_base->lo_U = losc_localizer_base_lo_U; 52 | return p_base; 53 | } 54 | 55 | //********************************************** 56 | // ==> Binding `losc::LoscLocalizerV2` methods. 57 | //********************************************** 58 | LoscLocalizerV2 *losc_localizer_v2_create(const losc_matrix *C_lo_basis, 59 | const losc_matrix *H_ao, 60 | const losc_matrix *D_ao[3]) 61 | { 62 | using losc::RefConstMat; 63 | using losc::vector; 64 | // create a real `losc::LoscLocalizerV2` object. 65 | vector D_ao_ref; 66 | for (size_t i = 0; i < 3; ++i) { 67 | D_ao_ref.push_back(losc_matrix_to_eigen_const(D_ao[i])); 68 | } 69 | losc::LocalizerV2 *p_v2 = 70 | new losc::LocalizerV2(losc_matrix_to_eigen_const(C_lo_basis), 71 | losc_matrix_to_eigen_const(H_ao), D_ao_ref); 72 | 73 | // create a `LoscLocalizerV2` struct that holds a bunch of function 74 | // pointers. 75 | auto rst = new LoscLocalizerV2; 76 | // Assign member variables. 77 | rst->_p_v2 = reinterpret_cast<_LoscLocalizerV2 *>(p_v2); 78 | rst->p_base = create_losc_localizer_base(p_v2); 79 | 80 | // Assign new function pointers here in the future, if we want to export 81 | // new functions in `losc::CurvatureV1`. 82 | return rst; 83 | } 84 | 85 | void *_losc_localizer_v2_free(LoscLocalizerV2 **pptr_self) 86 | { 87 | if (*pptr_self) { 88 | auto self = (*pptr_self); 89 | // free `LoscLocalizerBase` struct. 90 | delete self->p_base; 91 | // free `losc::LocalizerV2` class. 92 | delete reinterpret_cast(self->_p_v2); 93 | // free `LoscLocalizerV2` struct. 94 | delete self; 95 | // set self pointer to null. 96 | *pptr_self = nullptr; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/c_losc/matrix.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file matrix.cpp 3 | * @brief The implementation of matrix C interface. 4 | * 5 | * This is the implementation of the matrix interface, not the matrix itself. 6 | * The implementation of matrix is hid internally and not exposed to the 7 | * C users intentionally. 8 | */ 9 | #include "matrix_impl.hpp" 10 | #include 11 | 12 | // ==> export to C functions. 13 | extern "C" { 14 | losc_matrix *losc_matrix_create(size_t row, size_t col) 15 | { 16 | return new losc_matirx(row, col); 17 | } 18 | 19 | losc_matrix *losc_matrix_create_from_data(size_t row, size_t col, double *data) 20 | { 21 | return new losc_matirx(row, col, data); 22 | } 23 | 24 | void _losc_matrix_free(losc_matrix **pptr_m) 25 | { 26 | if (pptr_m) { 27 | delete (*pptr_m); 28 | } 29 | } 30 | 31 | double *losc_matrix_data(losc_matrix *m) { return m->data_; } 32 | 33 | const double *losc_matrix_data_const(const losc_matrix *m) { return m->data_; } 34 | 35 | size_t losc_matrix_rows(const losc_matrix *m) { return m->row_; } 36 | 37 | size_t losc_matrix_cols(const losc_matrix *m) { return m->col_; } 38 | } 39 | -------------------------------------------------------------------------------- /src/c_losc/matrix_impl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_C_LOSC_MATRIX_IMPL_HPP_ 2 | #define _LOSC_SRC_C_LOSC_MATRIX_IMPL_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * A simple matrix struct that is used to communicate matrix data between 10 | * the users and LOSC library. 11 | */ 12 | class losc_matrix { 13 | public: 14 | double *data_; 15 | size_t row_; 16 | size_t col_; 17 | bool own_data_; 18 | 19 | losc_matrix(size_t row, size_t col) : row_{row}, col_{col} 20 | { 21 | data_ = new double[row_ * col_]; 22 | own_data_ = true; 23 | } 24 | 25 | losc_matrix(size_t row, size_t col, double *data) 26 | : row_{row}, col_{col}, data_{data}, own_data_{false} 27 | { 28 | if (row_ != 0 && col_ != 0 && data_ == nullptr) { 29 | throw losc::exception::LoscException( 30 | "losc_matrix: detect null pointer to an non-empty matrix."); 31 | } 32 | } 33 | 34 | ~losc_matrix() 35 | { 36 | if (own_data_) 37 | delete[] data_; 38 | } 39 | }; 40 | 41 | /** 42 | * Map losc_matrix object to a const Eigen::Ref object. 43 | */ 44 | inline losc::RefConstMat 45 | losc_matrix_to_eigen_const(const losc_matrix *m) 46 | { 47 | return losc::MapConstMat(m->data_, m->row_, m->col_); 48 | } 49 | 50 | /** 51 | * Map losc_matrix object to a Eigen::Ref object. 52 | */ 53 | inline losc::RefMat losc_matrix_to_eigen(const losc_matrix *m) 54 | { 55 | return losc::MapMat(m->data_, m->row_, m->col_); 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME ${PROJECT_LOSC}) 2 | 3 | option(OPENMP "Enable openmp" On) 4 | # enable openmp or not. 5 | if (OPENMP) 6 | message(STATUS "Openmp is enabled.") 7 | add_compile_definitions(_OPENMP) 8 | find_package(OpenMP) 9 | if(OpenMP_CXX_FOUND) 10 | message(STATUS "Found openmp for CXX.") 11 | else() 12 | message(FATAL_ERROR "Fail to find openmp for CXX. Abort compilation.") 13 | endif() 14 | else() 15 | message(STATUS "Openmp is disabled, use `cmake -DOPENMP=on` to turn on.") 16 | endif() 17 | 18 | # sources 19 | file(GLOB SOURCES "*.cpp") 20 | set(LOSC_PUBLIC_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") 21 | 22 | # ==> build losc library <== 23 | add_library( 24 | ${PROJECT_NAME} SHARED 25 | ${SOURCES}) 26 | 27 | target_link_libraries( 28 | ${PROJECT_NAME} 29 | PUBLIC 30 | Eigen3::Eigen) 31 | 32 | if (OPENMP) 33 | target_link_libraries( 34 | ${PROJECT_NAME} 35 | PUBLIC 36 | OpenMP::OpenMP_CXX) 37 | endif() 38 | 39 | target_include_directories( 40 | ${PROJECT_NAME} 41 | PUBLIC 42 | ${LOSC_PUBLIC_INCLUDE_DIR}) 43 | 44 | # ==> install losc library <== 45 | install(TARGETS ${PROJECT_NAME} DESTINATION liblosc/losc) 46 | install(DIRECTORY "${LOSC_PUBLIC_INCLUDE_DIR}/losc" DESTINATION liblosc/losc/include) 47 | -------------------------------------------------------------------------------- /src/losc/correction.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace losc { 8 | 9 | void C_API_ao_hamiltonian_correction(ConstRefMat &S, ConstRefMat &C_lo, 10 | ConstRefMat &Curvature, 11 | ConstRefMat &LocalOcc, RefMat H_losc) 12 | { 13 | const size_t nlo = C_lo.cols(); 14 | const size_t nbasis = C_lo.rows(); 15 | 16 | if (nlo > nbasis) { 17 | throw exception::DimensionError( 18 | "losc::ao_hamiltonian_correction(): the number of LOs is larger " 19 | "than the number of AOs."); 20 | } 21 | if (!mtx_match_dimension(S, nbasis, nbasis)) { 22 | throw exception::DimensionError( 23 | S, nbasis, nbasis, 24 | "losc::ao_hamiltonian_correction(): mismatch AO overlap matrix."); 25 | } 26 | if (!mtx_match_dimension(Curvature, nlo, nlo)) { 27 | throw exception::DimensionError( 28 | Curvature, nlo, nlo, 29 | "losc::ao_hamiltonian_correction(): mismatch curvature matrix."); 30 | } 31 | if (!mtx_match_dimension(LocalOcc, nlo, nlo)) { 32 | throw exception::DimensionError(LocalOcc, nlo, nlo, 33 | "losc::ao_hamiltonian_correction(): " 34 | "mismatch local occupation matrix."); 35 | } 36 | 37 | // build A matrix. 38 | LOSCMatrix A(nlo, nlo); 39 | for (size_t i = 0; i < nlo; ++i) { 40 | for (size_t j = 0; j <= i; ++j) { 41 | const double K_ij = Curvature(i, j); 42 | const double L_ij = LocalOcc(i, j); 43 | if (i != j) { 44 | A(i, j) = -K_ij * L_ij; 45 | A(j, i) = A(i, j); 46 | } else { 47 | A(i, j) = 0.5 * K_ij - K_ij * L_ij; 48 | } 49 | } 50 | } 51 | 52 | H_losc = S * C_lo * A * C_lo.transpose() * S; 53 | } 54 | 55 | LOSCMatrix ao_hamiltonian_correction(ConstRefMat &S, ConstRefMat &C_lo, 56 | ConstRefMat &Curvature, 57 | ConstRefMat &LocalOcc) 58 | { 59 | const size_t nbasis = S.cols(); 60 | LOSCMatrix H_losc(nbasis, nbasis); 61 | C_API_ao_hamiltonian_correction(S, C_lo, Curvature, LocalOcc, H_losc); 62 | return std::move(H_losc); 63 | } 64 | 65 | double energy_correction(ConstRefMat &Curvature, ConstRefMat &LocalOcc) 66 | { 67 | const size_t nlo = Curvature.rows(); 68 | if (!mtx_match_dimension(Curvature, nlo, nlo)) { 69 | throw exception::DimensionError( 70 | Curvature, nlo, nlo, 71 | "losc::energy_correction(): mismatch curvature matrix."); 72 | } 73 | if (!mtx_match_dimension(LocalOcc, nlo, nlo)) { 74 | throw exception::DimensionError(LocalOcc, nlo, nlo, 75 | "losc::energy_correction(): " 76 | "mismatch local occupation matrix."); 77 | } 78 | 79 | double energy = 0.0; 80 | for (size_t i = 0; i < nlo; ++i) { 81 | energy += 82 | 0.5 * Curvature(i, i) * LocalOcc(i, i) * (1.0 - LocalOcc(i, i)); 83 | for (size_t j = 0; j < i; ++j) { 84 | energy -= Curvature(i, j) * LocalOcc(i, j) * LocalOcc(i, j); 85 | } 86 | } 87 | return energy; 88 | } 89 | 90 | void C_API_orbital_energy_post_scf(ConstRefMat &H_dfa, ConstRefMat &H_losc, 91 | ConstRefMat &C_co, double *eig) 92 | { 93 | const size_t nbasis = C_co.rows(); 94 | const size_t nlo = C_co.cols(); 95 | 96 | if (!mtx_match_dimension(H_dfa, nbasis, nbasis)) { 97 | throw exception::DimensionError(H_dfa, nbasis, nbasis, 98 | "losc::post_scf_orbital_energy(): " 99 | "mismatch DFA Hamiltonian matrix."); 100 | } 101 | if (!mtx_match_dimension(H_losc, nbasis, nbasis)) { 102 | throw exception::DimensionError( 103 | H_losc, nbasis, nbasis, 104 | "losc::post_scf_orbital_energy(): " 105 | "mismatch LOSC effective Hamiltonian matrix."); 106 | } 107 | 108 | LOSCMatrix H_tot = H_dfa + H_losc; 109 | for (size_t i = 0; i < nlo; ++i) { 110 | eig[i] = C_co.col(i).transpose() * H_tot * C_co.col(i); 111 | } 112 | } 113 | 114 | vector orbital_energy_post_scf(ConstRefMat &H_dfa, ConstRefMat &H_losc, 115 | ConstRefMat &C_co) 116 | { 117 | const size_t n = C_co.cols(); 118 | vector eig(n, 0); 119 | C_API_orbital_energy_post_scf(H_dfa, H_losc, C_co, eig.data()); 120 | return std::move(eig); 121 | } 122 | 123 | } // namespace losc 124 | -------------------------------------------------------------------------------- /src/losc/curvature.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | 5 | namespace losc { 6 | 7 | using exception::DimensionError; 8 | 9 | CurvatureBase::CurvatureBase(const DFAInfo &dfa_info, ConstRefMat &df_pii, 10 | ConstRefMat &df_Vpq_inverse, ConstRefMat &grid_lo, 11 | ConstRefVec &grid_weight) 12 | : npts_{grid_weight.size()}, nlo_{df_pii.cols()}, 13 | nfitbasis_{df_pii.rows()}, dfa_info_{dfa_info}, df_pii_{df_pii}, 14 | df_Vpq_inverse_{df_Vpq_inverse}, grid_lo_{grid_lo}, grid_weight_{ 15 | grid_weight} 16 | { 17 | if (!mtx_match_dimension(df_Vpq_inverse_, nfitbasis_, nfitbasis_)) { 18 | throw DimensionError( 19 | df_Vpq_inverse_, nfitbasis_, nfitbasis_, 20 | "wrong dimension for density fitting Vpq inverse matrix."); 21 | } 22 | if (!mtx_match_dimension(grid_lo_, npts_, nlo_)) { 23 | throw DimensionError(grid_lo_, npts_, nlo_, 24 | "wrong dimension for grid value of LOs."); 25 | } 26 | if (grid_weight_.size() != npts_) { 27 | throw DimensionError(grid_weight_, npts_, 1, 28 | "wrong dimension for grid weights."); 29 | } 30 | } 31 | 32 | namespace utils { 33 | 34 | /** 35 | * @note This function will not track if the matrix `df_pii` is fully filled. 36 | * The user should be carefully traverse all the blocks of `df_pmn_block`. 37 | */ 38 | void convert_df_pmn2pii_blockwise(const vector &p_index, 39 | ConstRefMat &df_pmn_block, ConstRefMat &C_lo, 40 | RefMat df_pii) 41 | { 42 | // i, j: LO index. 43 | // p, q: fitbasis index. 44 | // m, n: AO basis index. 45 | 46 | // (p|ii): [nfitbasis, nlo]. 47 | const size_t nfitbasis = df_pii.rows(); 48 | const size_t nbasis = C_lo.rows(); 49 | const size_t nlo = C_lo.cols(); 50 | 51 | // check input dimension. 52 | if (df_pmn_block.cols() != nbasis * (nbasis + 1) / 2) 53 | throw exception::DimensionError("Wrong dimension of df_pmn_block."); 54 | if (df_pii.rows() != nfitbasis && df_pii.cols() != nlo) 55 | throw exception::DimensionError("Wrong dimension of df_pii."); 56 | if (p_index.size() != df_pmn_block.rows()) 57 | throw exception::DimensionError( 58 | "number of rows in matrix df_pii dose not match with p index."); 59 | 60 | for (size_t pi = 0; pi < p_index.size(); ++pi) { 61 | const size_t p = p_index[pi]; 62 | // For each p0 (p0|mn), the (m, n) block has dimension: 63 | // [nbasis x nbasis]. 64 | LOSCMatrix df_pmn_p0_mn(nbasis, nbasis); 65 | for (size_t m = 0; m < nbasis; ++m) { 66 | for (size_t n = 0; n <= m; ++n) { 67 | const size_t mn = m * (m + 1) / 2 + n; 68 | df_pmn_p0_mn(m, n) = df_pmn_block(pi, mn); 69 | } 70 | } 71 | mtx_to_symmetric(df_pmn_p0_mn, "L"); 72 | 73 | // For each p0 (p0|in), the (i, n) block dimension: 74 | // [nlo x nbasis]. 75 | // Formula: (p0|in) = C_lo^T * (p|mn). 76 | LOSCMatrix df_pmn_p0_in(nlo, nbasis); 77 | df_pmn_p0_in.noalias() = C_lo.transpose() * df_pmn_p0_mn; 78 | 79 | // calculate element (p|ii) 80 | for (size_t i = 0; i < nlo; ++i) { 81 | df_pii(p, i) = df_pmn_p0_in.row(i).dot(C_lo.col(i)); 82 | } 83 | } 84 | } 85 | 86 | } // namespace utils 87 | 88 | } // namespace losc 89 | -------------------------------------------------------------------------------- /src/losc/curvature_v1.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace losc { 8 | 9 | LOSCMatrix CurvatureV1::compute_kappa_J() const 10 | { 11 | // K_ij = V_{pq}^-1 12 | return df_pii_.transpose() * df_Vpq_inverse_ * df_pii_; 13 | } 14 | 15 | LOSCMatrix CurvatureV1::compute_kappa_xc() const 16 | { 17 | LOSCMatrix kappa_xc(nlo_, nlo_); 18 | kappa_xc.setZero(); 19 | 20 | // The LO grid value matrix has dimension of (npts, nlo), which could be 21 | // very large. To limit the memory usage on LO grid value, we build it by 22 | // blocks. For now we limit the memory usage to be 1GB. 23 | const size_t block_size = 24 | 1000ULL * 1000ULL * 1000ULL / sizeof(double) / nlo_; 25 | size_t nBLK = npts_ / block_size; 26 | const size_t res = npts_ % block_size; 27 | if (res != 0) { 28 | nBLK += 1; 29 | } 30 | #ifdef _OPENMP 31 | #pragma omp parallel for schedule(dynamic) 32 | #endif 33 | // loop over all the blocks of grid. 34 | for (size_t n = 0; n < nBLK; ++n) { 35 | size_t size = block_size; 36 | if (n == nBLK - 1 && res != 0) 37 | size = res; 38 | 39 | const auto grid_lo_block = 40 | grid_lo_.block(n * block_size, 0, size, nlo_); 41 | const auto wt = grid_weight_.segment(n * block_size, size); 42 | 43 | // sum over current block contribution to kappa xc. 44 | for (size_t ip = 0; ip < size; ++ip) { 45 | const double wt_value = wt[ip]; 46 | for (size_t i = 0; i < nlo_; ++i) { 47 | for (size_t j = 0; j <= i; ++j) { 48 | const double pi = grid_lo_block(ip, i); 49 | const double pj = grid_lo_block(ip, j); 50 | kappa_xc(i, j) += wt_value * std::pow(pi * pi, 2.0 / 3.0) * 51 | std::pow(pj * pj, 2.0 / 3.0); 52 | } 53 | } 54 | } 55 | } 56 | mtx_to_symmetric(kappa_xc, "L"); 57 | 58 | return kappa_xc; 59 | } 60 | 61 | void CurvatureV1::C_API_kappa(RefMat K) const 62 | { 63 | if (!mtx_match_dimension(K, nlo_, nlo_)) { 64 | throw exception::DimensionError( 65 | K, nlo_, nlo_, 66 | "CurvatureV1::kappa(): wrong dimension of the input kappa matrix."); 67 | } 68 | LOSCMatrix kappa_J = compute_kappa_J(); 69 | LOSCMatrix kappa_xc = compute_kappa_xc(); 70 | K.noalias() = (1 - dfa_info_.hf_x()) * kappa_J - 71 | dfa_info_.gga_x() * (2.0 * tau_ * cx_ / 3.0) * kappa_xc; 72 | } 73 | 74 | } // namespace losc 75 | -------------------------------------------------------------------------------- /src/losc/curvature_v2.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | namespace losc { 7 | 8 | void CurvatureV2::C_API_kappa(RefMat kappa2) const 9 | { 10 | if (!mtx_match_dimension(kappa2, nlo_, nlo_)) { 11 | throw exception::DimensionError( 12 | kappa2, nlo_, nlo_, 13 | "CurvatureV2::kappa(): wrong dimension of the input kappa matrix."); 14 | } 15 | 16 | // construct absolute overlap under LO. 17 | LOSCMatrix S_lo(nlo_, nlo_); 18 | S_lo.setZero(); 19 | // The LO grid value matrix has dimension of (npts, nlo), which could be 20 | // very large. To limit the memory usage on LO grid value, we build it by 21 | // blocks. For now we limit the memory usage to be 1GB. 22 | const size_t block_size = 23 | 1000ULL * 1000ULL * 1000ULL / sizeof(double) / nlo_; 24 | size_t nBLK = npts_ / block_size; 25 | const size_t res = npts_ % block_size; 26 | if (res != 0) { 27 | nBLK += 1; 28 | } 29 | #ifdef _OPENMP 30 | #pragma omp parallel for schedule(dynamic) 31 | #endif 32 | // loop over all the blocks of grid. 33 | for (size_t n = 0; n < nBLK; ++n) { 34 | size_t size = block_size; 35 | if (n == nBLK - 1 && res != 0) 36 | size = res; 37 | 38 | const auto grid_lo_block = 39 | grid_lo_.block(n * block_size, 0, size, nlo_); 40 | const auto wt = grid_weight_.segment(n * block_size, size); 41 | 42 | // sum over current block contribution to the LO overlap. 43 | for (size_t ip = 0; ip < size; ++ip) { 44 | const double wt_value = wt[ip]; 45 | for (size_t i = 0; i < nlo_; ++i) { 46 | for (size_t j = 0; j <= i; ++j) { 47 | const double pi = grid_lo_block(ip, i); 48 | const double pj = grid_lo_block(ip, j); 49 | S_lo(i, j) += wt_value * std::abs(pi * pj); 50 | } 51 | } 52 | } 53 | } 54 | mtx_to_symmetric(S_lo, "L"); 55 | 56 | // build the curvature version 1. 57 | CurvatureV1 kappa1_man(dfa_info_, df_pii_, df_Vpq_inverse_, grid_lo_, 58 | grid_weight_); 59 | LOSCMatrix kappa1 = kappa1_man.kappa(); 60 | 61 | // build LOSC2 kappa matrix: 62 | // K2[ij] = erf(tau * S[ij]) * sqrt(abs(K1[ii] * K1[jj])) + erfc(tau * 63 | // S[ij]) * K][ij] 64 | using std::abs; 65 | using std::erf; 66 | using std::erfc; 67 | using std::sqrt; 68 | for (size_t i = 0; i < nlo_; ++i) { 69 | const double K1_ii = kappa1(i, i); 70 | kappa2(i, i) = K1_ii; 71 | for (size_t j = 0; j < i; ++j) { 72 | const double S_ij = S_lo(i, j); 73 | const double K1_ij = kappa1(i, j); 74 | const double K1_jj = kappa1(j, j); 75 | const double f = zeta_ * S_ij; 76 | kappa2(i, j) = erf(f) * sqrt(abs(K1_ii * K1_jj)) + erfc(f) * K1_ij; 77 | kappa2(j, i) = kappa2(i, j); 78 | } 79 | } 80 | } 81 | 82 | } // namespace losc 83 | -------------------------------------------------------------------------------- /src/losc/eigen_helper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_LOSC_EIGEN_HELPER_HPP_ 2 | #define _LOSC_SRC_LOSC_EIGEN_HELPER_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace losc { 10 | 11 | using std::string; 12 | 13 | /** 14 | * @brief Check if the matrix is square or not. 15 | * @return bool 16 | */ 17 | inline bool mtx_is_square(ConstRefMat &m) { return m.rows() == m.cols(); } 18 | 19 | /** 20 | * @brief Check if the matrix's dimension agrees with input expectation. 21 | * @return bool 22 | */ 23 | inline bool mtx_match_dimension(ConstRefMat &m, int row, int col) 24 | { 25 | return (m.rows() == row) && (m.cols() == col); 26 | } 27 | 28 | /** 29 | * @brief Make the matrix to be symmetric. 30 | * 31 | * @param [in] uplo: when \p uplo equals to "U", the upper triangular part 32 | * is used. when \p uplo equals to "L", the lower triangular part is used. 33 | */ 34 | inline void mtx_to_symmetric(RefMat m, const string &uplo) 35 | { 36 | const size_t row = m.rows(); 37 | if (!mtx_is_square(m)) { 38 | throw exception::DimensionError( 39 | "Cannot symmetrize a matrix that is not squared."); 40 | } 41 | if (uplo == "U") { 42 | for (size_t i = 0; i < row; i++) { 43 | for (size_t j = 0; j < i; j++) { 44 | m(i, j) = m(j, i); 45 | } 46 | } 47 | } else if (uplo == "L") { 48 | for (size_t i = 0; i < row; i++) { 49 | for (size_t j = 0; j < i; j++) { 50 | m(j, i) = m(i, j); 51 | } 52 | } 53 | } else { 54 | throw exception::LoscException( 55 | "Implementation Error: wrong choice to symmetrize a matrix."); 56 | } 57 | } 58 | 59 | /** 60 | * apply rotation matrix to x and y vector. x and y can represent either row or 61 | * column vector. 62 | */ 63 | template inline void rotate_two_vectors(T &&x, T &&y, double theta) 64 | { 65 | const double c = cos(theta); 66 | const double s = sin(theta); 67 | // Eigen by defaul use lazy evaluation, which means preferring expression 68 | // rather than evaluation of the expression. Here, we need to turn off the 69 | // lazy evaluation and force it to evalate into a temporary vector to store 70 | // in variable `t`. 71 | auto t = (x * c + y * s).eval(); 72 | y = x * -s + y * c; 73 | x = t; 74 | } 75 | 76 | } // namespace losc 77 | #endif 78 | -------------------------------------------------------------------------------- /src/losc/exception.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // std::stringstream 3 | 4 | namespace losc { 5 | namespace exception { 6 | 7 | void LoscException::make_message(const char *msg) 8 | { 9 | stringstream s; 10 | s << std::endl; 11 | s << "Fatal error: " << msg << std::endl; 12 | msg_ = s.str(); 13 | } 14 | 15 | DimensionError::DimensionError(ConstRefMat &A, size_t expected_row, 16 | size_t expected_col, const string &msg) 17 | : LoscException("Wrong matrix dimension.") 18 | { 19 | stringstream s; 20 | s << "Description: " << msg << std::endl; 21 | s << "Details: " 22 | << "Current matrix dimension: [" << A.rows() << ", " << A.cols() << "]" 23 | << std::endl; 24 | s << " " 25 | << "Expected matrix dimension: [" << expected_row << ", " 26 | << expected_col << "]" << std::endl; 27 | msg_ = s.str(); 28 | } 29 | 30 | DimensionError::DimensionError(const string &msg) 31 | : LoscException("Dimension error.") 32 | { 33 | stringstream s; 34 | s << "Description: " << msg << std::endl; 35 | msg_ = s.str(); 36 | } 37 | 38 | } // namespace exception 39 | } // namespace losc 40 | -------------------------------------------------------------------------------- /src/losc/local_occupation.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | namespace losc { 7 | 8 | LOSCMatrix local_occupation(ConstRefMat &C_lo, ConstRefMat &S, ConstRefMat &D) 9 | { 10 | const size_t nlo = C_lo.cols(); 11 | LOSCMatrix local_occ(nlo, nlo); 12 | C_API_local_occupation(C_lo, S, D, local_occ); 13 | return std::move(local_occ); 14 | } 15 | 16 | void C_API_local_occupation(ConstRefMat &C_lo, ConstRefMat &S, ConstRefMat &D, 17 | RefMat LocalOcc) 18 | { 19 | const size_t nlo = C_lo.cols(); 20 | const size_t nbasis = C_lo.rows(); 21 | 22 | if (nlo > nbasis) { 23 | throw exception::DimensionError( 24 | "wrong dimension for LO coefficient matrix: number of LO is larger " 25 | "than the number of AO."); 26 | } 27 | if (!mtx_match_dimension(S, nbasis, nbasis)) { 28 | throw exception::DimensionError( 29 | S, nbasis, nbasis, "wrong dimension for AO overlap matrix."); 30 | } 31 | if (!mtx_match_dimension(D, nbasis, nbasis)) { 32 | throw exception::DimensionError(D, nbasis, nbasis, 33 | "wrong dimension for density matrix."); 34 | } 35 | if (!mtx_match_dimension(LocalOcc, nlo, nlo)) { 36 | throw exception::DimensionError( 37 | LocalOcc, nlo, nlo, "wrong dimension for local occupation matrix."); 38 | } 39 | 40 | LocalOcc = C_lo.transpose() * S * D * S * C_lo; 41 | } 42 | 43 | } // namespace losc 44 | -------------------------------------------------------------------------------- /src/losc/localization.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen_helper.hpp" 2 | #include 3 | #include 4 | 5 | namespace losc { 6 | 7 | void LocalizerBase::set_u_guess(RefMat U, const string &guess) const 8 | { 9 | if (guess == "identity") 10 | U.setIdentity(); 11 | // TODO 12 | else if (guess == "random") { 13 | } else if (guess == "random_fixed_seed") { 14 | } else { 15 | throw exception::LoscException( 16 | "Unknown initial guess of U matrix for localization."); 17 | } 18 | } 19 | 20 | void LocalizerBase::set_u_guess(RefMat U, ConstRefMat &U_guess, 21 | double threshold) const 22 | { 23 | if (!mtx_match_dimension(U, nlo_, nlo_)) { 24 | throw exception::DimensionError( 25 | U, nlo_, nlo_, "wrong dimension for localization U matrix."); 26 | } 27 | if (!U.isUnitary(threshold)) { 28 | throw exception::LoscException("Invalid U matrix: input U matrix " 29 | "is not unitary"); 30 | } 31 | U = U_guess; 32 | } 33 | 34 | LocalizerBase::LocalizerBase(ConstRefMat &C_lo_basis) 35 | : nbasis_{C_lo_basis.rows()}, nlo_{C_lo_basis.cols()}, 36 | C_lo_basis_{C_lo_basis}, nsteps_{0}, converged_{false} 37 | { 38 | if (!mtx_match_dimension(C_lo_basis_, nbasis_, nlo_)) { 39 | throw exception::DimensionError(C_lo_basis_, nbasis_, nlo_, 40 | "LocalizerBase: wrong dimension for " 41 | "LO basis matrix under AO."); 42 | } 43 | } 44 | } // namespace losc 45 | -------------------------------------------------------------------------------- /src/psi4_losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME psi4_losc) 2 | 3 | # sources 4 | file(GLOB SOURCES "*.py") 5 | file(COPY ${SOURCES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 6 | 7 | # ==> install py_losc module <== 8 | install(FILES ${SOURCES} DESTINATION liblosc/psi4_losc) 9 | -------------------------------------------------------------------------------- /src/psi4_losc/__init__.py: -------------------------------------------------------------------------------- 1 | import psi4_losc.losc_options 2 | 3 | #: The Options class object that controls the LOSC calculations in `psi4_losc` 4 | #: module. 5 | #: 6 | #: See also 7 | #: -------- 8 | #: psi4_losc.losc_options.Options 9 | options = psi4_losc.losc_options.Options() 10 | 11 | import psi4_losc.scf 12 | import psi4_losc.build_scf_wfn 13 | from psi4_losc.psi4_losc import * 14 | -------------------------------------------------------------------------------- /src/psi4_losc/build_scf_wfn.py: -------------------------------------------------------------------------------- 1 | """Import this module will update function `psi4.proc.scf_wavefunction_factory()` 2 | defined in psi4 to be an extended version. Making such update is to enable 3 | `psi4.energy()` to be compatible with LOSC calculation. 4 | """ 5 | 6 | import psi4 7 | import py_losc 8 | import numpy as np 9 | 10 | # Function `psi4.proc.scf_wavefunction_factory()` will be extended in this 11 | # module. Here, we save the original one first. 12 | _psi4_scf_wavefunction_factory = psi4.driver.scf_wavefunction_factory 13 | 14 | 15 | def _to_losc_wfn(wfn, losc_data): 16 | """ 17 | Update psi4 wfn methods to have LOSC contributions by overriding some 18 | key functions. 19 | """ 20 | self = wfn 21 | original_form_F = self.form_F 22 | origninal_compute_E = self.compute_E 23 | nspin = 1 if wfn.same_a_b_orbs() and wfn.same_a_b_dens() else 2 24 | curvature = losc_data.get('curvature', []) 25 | C_lo = losc_data.get('C_lo', []) 26 | E_losc = [0] # we need to use list to let inner function has modify access. 27 | 28 | def form_F(): 29 | # Build DFA Fock matrix. This will update `wfn.Fa()` and `wfn.Fb()`. 30 | original_form_F() 31 | 32 | # ==> LOSC contributions <== 33 | # 1. Build LOSC effective Hamiltonian and add it to internal 34 | # wavefunction Fock matrix. 35 | # 2. Build LOSC correction to total energy 36 | S = np.asarray(self.S()) 37 | D = [np.asarray(self.Da()), np.asarray(self.Db())] 38 | F = [np.asarray(self.Fa()), np.asarray(self.Fb())] 39 | E_losc[0] = 0 40 | for s in range(nspin): 41 | # build LOSC local occupation matrix 42 | local_occ = py_losc.local_occupation(C_lo[s], S, D[s]) 43 | # build LOSC effective Fock matrix 44 | H_losc = py_losc.ao_hamiltonian_correction( 45 | S, C_lo[s], curvature[s], local_occ) 46 | F[s][:] += H_losc 47 | # form LOSC energy correction 48 | E_losc[0] += py_losc.energy_correction(curvature[s], local_occ) 49 | if nspin == 1: 50 | E_losc[0] *= 2 51 | 52 | def compute_E(): 53 | # Compute DFA total energy 54 | E_dfa = origninal_compute_E() 55 | # Add LOSC energy. Register LOSC energy into wfn energetics table. 56 | self.set_energies('LOSC energy', E_losc[0]) 57 | E_tot = E_dfa + E_losc[0] 58 | return E_tot 59 | 60 | # override wfn methods. 61 | self.form_F = form_F 62 | self.compute_E = compute_E 63 | 64 | 65 | def _scf_wavefunction_factory_extended_version(name, ref_wfn, reference, **kwargs): 66 | """ 67 | Build an SCF wavefunction. This is the extended version for 68 | `psi4.proc.scf_wavefunction_factory()`. 69 | """ 70 | # build psi4 SCF wfn. 71 | reference = reference.upper() 72 | wfn = _psi4_scf_wavefunction_factory(name, ref_wfn, reference, **kwargs) 73 | 74 | # update to LOSC wavefunction behavior if it is necessary. 75 | losc_data = kwargs.get('losc_data', {}) 76 | if losc_data: 77 | # same sanity checks 78 | curvature = losc_data.get('curvature', []) 79 | C_lo = losc_data.get('C_lo', []) 80 | if not curvature: 81 | raise Exception('need LOSC curvature matrix to build LOSC class.') 82 | if not C_lo: 83 | raise Exception('need LOSC localized orbital to build LOSC class.') 84 | # restricted 85 | if reference in ["RHF", "RKS"]: 86 | if len(curvature) != 1 or len(C_lo) != 1: 87 | raise Exception( 88 | 'restricted case: size of curvature or C_lo is not 1.') 89 | # unrestricted 90 | elif reference in ['UHF', 'UKS']: 91 | if len(curvature) != 2 or len(C_lo) != 2: 92 | raise Exception( 93 | 'unrestricted case: size of curvature or C_lo is not 2.') 94 | # error reference 95 | else: 96 | raise Exception( 97 | f"reference ({reference}) not supported for LOSC wavefunction.") 98 | 99 | # update to losc wfn. 100 | _to_losc_wfn(wfn, losc_data) 101 | return wfn 102 | 103 | 104 | # Here, we update `psi4.proc.scf_wavefunction_factory()` with the extended 105 | # version. 106 | psi4.driver.scf_wavefunction_factory = _scf_wavefunction_factory_extended_version 107 | # we need to update psi4.proc.scf_wavefunction_factory, 108 | # not psi4.driver.scf_wavefunction_factory. 109 | psi4.proc.scf_wavefunction_factory = _scf_wavefunction_factory_extended_version 110 | -------------------------------------------------------------------------------- /src/psi4_losc/diis.py: -------------------------------------------------------------------------------- 1 | """ 2 | DIIS algorithm for SCF procedure implemented with Python. 3 | 4 | Notes 5 | ----- 6 | This DIIS algorithm is used in self-implemented SCF procedure, that is 7 | `psi4_losc/scf.py` module (not the psi4 SCF procedure). 8 | """ 9 | 10 | import numpy as np 11 | import psi4 12 | 13 | class diis(object): 14 | """ 15 | A helper class to compute DIIS extrapolations. 16 | 17 | Notes 18 | ----- 19 | Equations taken from [Sherrill:1998], [Pulay:1980:393], & [Pulay:1969:197] 20 | Algorithms adapted from [Sherrill:1998] & [Pulay:1980:393] 21 | """ 22 | 23 | def __init__(self): 24 | """ 25 | Intializes the DIIS class. 26 | 27 | Parameters 28 | ---------- 29 | max_vec : int (default, 6) 30 | The maximum number of vectors to use. The oldest vector will be deleted. 31 | """ 32 | self.error = [] 33 | self.vector = [] 34 | self.max_vec = psi4.core.get_option('SCF', 'DIIS_MAX_VECS') 35 | 36 | def add(self, state, error): 37 | """ 38 | Adds a set of error and state vectors to the DIIS object. 39 | 40 | Parameters 41 | ---------- 42 | state : array_like 43 | The state vector to add to the DIIS object. 44 | error : array_like 45 | The error vector to add to the DIIS object. 46 | 47 | Returns 48 | ------- 49 | None 50 | """ 51 | 52 | error = np.array(error) 53 | state = np.array(state) 54 | if len(self.error) > 1: 55 | if self.error[-1].shape[0] != error.size: 56 | raise Exception("Error vector size does not match previous vector.") 57 | if self.vector[-1].shape != state.shape: 58 | raise Exception("Vector shape does not match previous vector.") 59 | 60 | self.error.append(error.ravel().copy()) 61 | self.vector.append(state.copy()) 62 | 63 | def extrapolate(self): 64 | """ 65 | Performs the DIIS extrapolation for the objects state and error vectors. 66 | 67 | Parameters 68 | ---------- 69 | None 70 | 71 | Returns 72 | ------ 73 | ret : ndarray 74 | The extrapolated next state vector 75 | 76 | """ 77 | 78 | # Limit size of DIIS vector 79 | diis_count = len(self.vector) 80 | 81 | if diis_count == 0: 82 | raise Exception("DIIS: No previous vectors.") 83 | if diis_count == 1: 84 | return self.vector[0] 85 | 86 | if diis_count > self.max_vec: 87 | # Remove oldest vector 88 | del self.vector[0] 89 | del self.error[0] 90 | diis_count -= 1 91 | 92 | # Build error matrix B 93 | B = np.empty((diis_count + 1, diis_count + 1)) 94 | B[-1, :] = -1 95 | B[:, -1] = -1 96 | B[-1, -1] = 0 97 | for num1, e1 in enumerate(self.error): 98 | B[num1, num1] = np.vdot(e1, e1) 99 | for num2, e2 in enumerate(self.error): 100 | if num2 >= num1: continue 101 | val = np.vdot(e1, e2) 102 | B[num1, num2] = B[num2, num1] = val 103 | 104 | # normalize 105 | #B[abs(B) < 1.e-14] = 1.e-14 106 | #B[:-1, :-1] /= np.abs(B[:-1, :-1]).max() 107 | 108 | # Build residual vector 109 | resid = np.zeros(diis_count + 1) 110 | resid[-1] = -1 111 | 112 | S = np.zeros(diis_count+1) 113 | is_zero = False 114 | for i in range(diis_count): 115 | if B[i, i] <= 0: 116 | is_zero = True 117 | break 118 | 119 | if is_zero: 120 | S[:] = 1.0 121 | else: 122 | S[:diis_count] = np.power(np.diag(B[:diis_count, :diis_count]), -1.0/2.0) 123 | S[diis_count] = 1.0 124 | 125 | for i in range(diis_count + 1): 126 | for j in range(diis_count + 1): 127 | B[i, j] *= S[i] * S[j] 128 | 129 | N = diis_count + 1 130 | B_psi = psi4.core.Matrix(N, N).from_array(B) 131 | B_psi.power(-1.0, 1.0e-12) 132 | B_inv = np.asarray(B_psi) 133 | 134 | 135 | # Solve pulay equations 136 | #ci = np.dot(np.linalg.pinv(B), resid) 137 | ci = np.dot(B_inv, resid) 138 | for i in range(diis_count + 1): 139 | ci[i] *= S[i] 140 | 141 | # combination of previous fock matrices 142 | V = np.zeros_like(self.vector[-1]) 143 | for num, c in enumerate(ci[:-1]): 144 | V += c * self.vector[num] 145 | 146 | return V 147 | -------------------------------------------------------------------------------- /src/py_losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME py_losc_core) 2 | project(${PROJECT_NAME} C CXX) 3 | 4 | # sources 5 | file(GLOB SOURCES "*.cpp") 6 | 7 | pybind11_add_module( 8 | ${PROJECT_NAME} SHARED 9 | ${SOURCES}) 10 | 11 | target_link_libraries( 12 | ${PROJECT_NAME} 13 | PUBLIC 14 | ${PROJECT_LOSC}) 15 | 16 | file(COPY __init__.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 17 | file(COPY py_losc.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 18 | 19 | # ==> install py_losc module <== 20 | install(TARGETS ${PROJECT_NAME} DESTINATION liblosc/py_losc) 21 | install(FILES __init__.py py_losc.py DESTINATION liblosc/py_losc) 22 | -------------------------------------------------------------------------------- /src/py_losc/__init__.py: -------------------------------------------------------------------------------- 1 | """Python interface for localized orbital scaling correction (LOSC) library. 2 | 3 | Notes 4 | ----- 5 | All the matrices are represented and stored in the 2-dimensional 6 | `numpy.array` object. The storage order of matrices is required to be 7 | C-style (row major). If the input matrix is not C-style, it will be converted 8 | interanally. 9 | 10 | Following notations are used in the docstrings: 11 | 12 | - LO: the localized orbital. 13 | - AO: the atomic orbitals. 14 | - CO: the canonical orbital. 15 | - nlo: the number of LOs. 16 | - nbasis: the number of AOs. 17 | - nfitbasis: the number of fitting basis for density fitting. 18 | - npts: the number of grids. 19 | """ 20 | 21 | # ==> Interface for LOSC corrections <== 22 | from py_losc.py_losc_core import ao_hamiltonian_correction 23 | from py_losc.py_losc_core import orbital_energy_post_scf 24 | from py_losc.py_losc_core import energy_correction 25 | 26 | # ==> Interface for LOSC local occupation <== 27 | from py_losc.py_losc_core import local_occupation 28 | 29 | 30 | # ==> Interface for LOSC localization <== 31 | from py_losc.py_losc import DFAInfo 32 | from py_losc.py_losc import CurvatureV1 33 | from py_losc.py_losc import CurvatureV2 34 | 35 | # ==> Interface for LOSC curvature matrix <== 36 | from py_losc.py_losc import LocalizerV2 37 | -------------------------------------------------------------------------------- /src/py_losc/export_correction.cpp: -------------------------------------------------------------------------------- 1 | #include "export_correction.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | void export_correction(py::module &m) 7 | { 8 | // ao_hamiltonian_correction 9 | m.def("ao_hamiltonian_correction", &losc::ao_hamiltonian_correction, 10 | R"pddoc( 11 | Calculate LOSC effective Hamiltonian under AO basis. 12 | 13 | Parameters 14 | ---------- 15 | S : numpy.ndarray 16 | AO overlap matrix with dimension [nbasis, nbasis]. 17 | C_lo : numpy.array 18 | LO coefficient matrix under AO basis with dimension of [nbasis, nbasis]. 19 | The coefficients of i-th LO is the i-th column of `C_lo`. 20 | Curvature : numpy.array 21 | LOSC curvature matrix with dimension [nlo, nlo]. 22 | LocalOcc : numpy.array 23 | LOSC local occupation matrix with dimension [nlo, nlo]. 24 | 25 | Returns 26 | ------- 27 | numpy.array 28 | The LOSC effective Hamiltonian under AOs with dimension [nbasis, nbasis]. 29 | 30 | See Also 31 | -------- 32 | CurvatureV1.kappa, CurvatureV2.kappa, local_occupation 33 | 34 | Notes 35 | ----- 36 | The LOSC effective Hamiltonian is constructed with LOs fixed. The 37 | expression of the effective Hamiltonian is shown as Eq. S25 in the 38 | supporting information of the `original LOSC paper 39 | `_. This effective Hamiltonian is exact 40 | in the `developed version of SCF-LOSC 41 | `_ 42 | )pddoc"); 43 | 44 | // energy_correction 45 | m.def("energy_correction", &losc::energy_correction, R"pddoc( 46 | Calculate the total energy correction from LOSC. 47 | 48 | Parameters 49 | ---------- 50 | Curvature : numpy.ndarray 51 | The LOSC curvature matrix with dimension [nlo, nlo]. 52 | LocalOcc: numpy.ndarray 53 | The LOSC local occupation matrix with dimension [nlo, nlo]. 54 | 55 | Returns 56 | ------- 57 | float 58 | The correction from LOSC to the total energy. 59 | 60 | See Also 61 | -------- 62 | CurvatureV1.kappa, CurvatureV2.kappa, local_occupation 63 | 64 | Notes 65 | ----- 66 | This is just the energy correction from LOSC, NOT the total energy of 67 | LOSC-DFA. Total energy of LOSC-DFA is ``E_losc_dfa = E_dfa + E_losc``. 68 | )pddoc"); 69 | 70 | // orbital_energy_post_scf 71 | m.def("orbital_energy_post_scf", &losc::orbital_energy_post_scf, 72 | R"pddoc( 73 | Calculate corrected orbital energy from LOSC in a post-SCF approach. 74 | 75 | 76 | 77 | Parameters 78 | ---------- 79 | H_dfa: np.ndarray [nbasis, nbasis] 80 | The DFA Hamiltonian under AOs. 81 | H_losc: np.ndarray [nbasis, nbasis] 82 | The LOSC effective Hamiltonian under AOs. 83 | C_co: np.ndarray [nbasis, n], n <= basis, which is the number of COs. 84 | The coefficient matrix of converged COs under AOs from DFA. 85 | 86 | Returns 87 | ------- 88 | out: list 89 | The corrected orbital energies from LOSC with size of n. The order of 90 | orbital energies match the order of input COs (order of columns in 91 | C_co matrix). 92 | 93 | See Also 94 | -------- 95 | ao_hamiltonian_correction 96 | 97 | Notes 98 | ----- 99 | This function gives the final corrected orbital energies from LOSC. 100 | Note the difference to the function `energy_correction`. 101 | 102 | The corrected orbital energies are the expectation values of converged 103 | DFA's COs on the LOSC-DFA Hamiltonian, that is, 104 | 105 | .. math:: \epsilon_i = \langle \psi_i | H_{\rm{dfa}} + H_{\rm{losc}} 106 | | \psi_i \rangle. 107 | 108 | 109 | This is just one of the ways to calculate the LOSC corrected orbital 110 | energy in a post-SCF LOSC calculation. It is the way usually used to produce 111 | results in the `published paper `_ 112 | for the post-SCF LOSC calculations. Besides this way, there are another two 113 | ways to calculate corrected orbital energies: (1) diagonalize the corrected 114 | LOSC-DFA Hamiltonian; (2) Follow 115 | `Eq. 11 `_ to calculate the corrections 116 | to orbital energies. These three ways usually produce similar results. 117 | )pddoc"); 118 | } 119 | -------------------------------------------------------------------------------- /src/py_losc/export_correction.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_PY_LOSC_EXPORT_CORRECTION_HPP_ 2 | #define _LOSC_SRC_PY_LOSC_EXPORT_CORRECTION_HPP_ 3 | 4 | #include 5 | namespace py = pybind11; 6 | 7 | void export_correction(py::module &m); 8 | #endif 9 | -------------------------------------------------------------------------------- /src/py_losc/export_curvature.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_PY_LOSC_EXPORT_CURVATURE_HPP_ 2 | #define _LOSC_SRC_PY_LOSC_EXPORT_CURVATURE_HPP_ 3 | 4 | #include 5 | namespace py = pybind11; 6 | 7 | void export_curvature_base(py::module &m); 8 | void export_curvature_v1(py::module &m); 9 | void export_curvature_v2(py::module &m); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/py_losc/export_local_occupation.cpp: -------------------------------------------------------------------------------- 1 | #include "export_local_occupation.hpp" 2 | #include 3 | #include 4 | 5 | void export_local_occupation(py::module &m) 6 | { 7 | // local_occupation 8 | m.def("local_occupation", &losc::local_occupation, 9 | R"pddoc( 10 | Calculate the LOSC local occupation matrix. 11 | 12 | Parameters 13 | ---------- 14 | C_lo : numpy.array 15 | The LO coefficient matrix. ``C_lo[:, i]`` is the coefficients of 16 | the i-th LO represented on AO. 17 | S: numpy.ndarray 18 | The AO overlap matrix with dimension [nbasis, nbasis]. 19 | D: numpy.ndarray 20 | The spin density matrix under AO with dimension [nbasis, nbasis]. 21 | 22 | Returns 23 | ------- 24 | numpy.ndarray 25 | The local occupation matrix with dimension [nlo, nlo]. 26 | 27 | See Also 28 | -------- 29 | LocalizerV2.lo 30 | 31 | Notes 32 | ----- 33 | The local occupation matrix is defined as 34 | 35 | .. math:: \lambda_{ij} = \langle \phi_i|\rho|\phi_j \rangle, 36 | 37 | where :math:`\lambda_{ij}` is the local occupation matrix element, 38 | :math:`\phi_i` and :math:`\phi_j` are the i-th and j-th localized orbital 39 | and :math:`\rho` is the spin density operator. 40 | )pddoc"); 41 | } 42 | -------------------------------------------------------------------------------- /src/py_losc/export_local_occupation.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_PY_LOSC_EXPORT_LOCAL_OCCUPATION_HPP_ 2 | #define _LOSC_SRC_PY_LOSC_EXPORT_LOCAL_OCCUPATION_HPP_ 3 | 4 | #include 5 | namespace py = pybind11; 6 | 7 | void export_local_occupation(py::module &m); 8 | #endif 9 | -------------------------------------------------------------------------------- /src/py_losc/export_localization.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_SRC_PY_LOSC_EXPORT_LOCALIZATION_HPP_ 2 | #define _LOSC_SRC_PY_LOSC_EXPORT_LOCALIZATION_HPP_ 3 | 4 | #include 5 | namespace py = pybind11; 6 | 7 | void export_localization_base(py::module &m); 8 | void export_localization_v2(py::module &m); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/py_losc/export_py_losc.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file export_py_losc.cpp 3 | * @brief Binding C++ LOSC library with Python with using pybind11 library. 4 | * 5 | * This is the main file in which the binding code is implemented. It merges 6 | * all the branches of binding code (for curvature, localization, ...) into one. 7 | * For details of binding code, see other `export_xxx.cpp` file. At the end, 8 | * these `export_xxx.cpp` files will be compiled to give a binary library 9 | * which serves as a customized C++ extension module to be used in Python. 10 | * 11 | * @note 12 | * 1. We don't want to the Python user to directly import the binary C++ 13 | * extension module, although it can be successfully imported. Instead, 14 | * we provide a Python module that further wraps the C++ extension module. 15 | * See `py_losc.py` for details. These python wrapping modules provide 16 | * better and much readable documentations. In addition, they also provide 17 | * some utility functions, which enriches the core classes and functions 18 | * are defined in C++ extension, to have better and easier usage in Python 19 | * for LOSC calculations. As a whole, the Python users only need to 20 | * import `py_losc.py` in their python code to use the LOSC library. 21 | * 22 | * For developers: 23 | * 1. Functions in `export_xxx.cpp` files that have documentation strings is the 24 | * final version of the exporting. 25 | * 2. Functions in `export_xxx.cpp` files that have NO documentation strings 26 | * may be further wrapped in python module to produce better implementation. 27 | * For example, CurvatureV2 class (its constructor) is further wrapped in 28 | * python module to enable the implicit conversion of storage order between 29 | * np.ndarray and Eigen::LOSCMatrix. 30 | */ 31 | 32 | #include "export_py_losc.hpp" 33 | #include "export_correction.hpp" 34 | #include "export_curvature.hpp" 35 | #include "export_local_occupation.hpp" 36 | #include "export_localization.hpp" 37 | 38 | PYBIND11_MODULE(PY_LOSC_MODULE_NAME, m) 39 | { 40 | m.doc() = "Localizer Orbital Scaling Correction (LOSC) Library"; 41 | 42 | // curvature 43 | export_curvature_base(m); 44 | export_curvature_v1(m); 45 | export_curvature_v2(m); 46 | 47 | // localization 48 | export_localization_base(m); 49 | export_localization_v2(m); 50 | 51 | // correction 52 | export_correction(m); 53 | 54 | // local_occ 55 | export_local_occupation(m); 56 | } 57 | -------------------------------------------------------------------------------- /src/py_losc/export_py_losc.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _LOSC_SRC_PY_LOSC_EXPORT_PY_LOSC_HPP_ 3 | #define _LOSC_SRC_PY_LOSC_EXPORT_PY_LOSC_HPP_ 4 | 5 | #define PY_LOSC_MODULE_NAME py_losc_core 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/pyscf_losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME pyscf_losc) 2 | 3 | # sources 4 | file(GLOB SOURCES "*.py") 5 | file(COPY ${SOURCES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 6 | 7 | # ==> install py_losc module <== 8 | install(FILES ${SOURCES} DESTINATION liblosc/pyscf_losc) 9 | 10 | -------------------------------------------------------------------------------- /src/pyscf_losc/__init__.py: -------------------------------------------------------------------------------- 1 | import pyscf_losc.losc_options 2 | options = pyscf_losc.losc_options.Options() 3 | from pyscf_losc.pyscf_losc import * 4 | 5 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(losc) 2 | -------------------------------------------------------------------------------- /tests/losc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_NAME losc_test) 2 | project(${PROJECT_NAME} C CXX) 3 | 4 | file(GLOB SOURCE 5 | "*.cpp" 6 | "*.cc") 7 | 8 | add_executable( 9 | ${PROJECT_NAME} 10 | ${SOURCE}) 11 | 12 | target_link_libraries( 13 | ${PROJECT_NAME} PUBLIC 14 | ${PROJECT_LOSC} 15 | gtest_main) 16 | 17 | add_test( 18 | NAME ${PROJECT_NAME} 19 | COMMAND ${PROJECT_NAME}) 20 | -------------------------------------------------------------------------------- /tests/losc/correction_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "matrix_helper.hpp" 11 | #include "matrix_io.hpp" 12 | #include 13 | 14 | using std::move; 15 | using std::string; 16 | using std::vector; 17 | using namespace losc; 18 | 19 | /** 20 | * Get Losc total energy correction from a txt file. 21 | * The txt file only contains one line. 22 | */ 23 | static double get_losc_E_correction(string &fname) 24 | { 25 | std::fstream fin; 26 | fin.open(fname); 27 | string energy_str; 28 | std::getline(fin, energy_str); 29 | fin.close(); 30 | return std::stod(energy_str); 31 | } 32 | 33 | struct CorrectionTest : public ::testing::TestWithParam { 34 | string file_path; 35 | string dir_path; 36 | 37 | virtual void SetUp() override 38 | { 39 | file_path = __FILE__; 40 | dir_path = file_path.substr(0, file_path.rfind("/")); 41 | } 42 | 43 | virtual void TearDown() override {} 44 | }; 45 | 46 | TEST_P(CorrectionTest, losc_Hamiltonian_correction) 47 | { 48 | // load data. 49 | string mol = GetParam(); 50 | const char *mol_str = mol.c_str(); 51 | string S_path = dir_path + "/data/" + mol + "/ao_overlap.txt"; 52 | string C_lo_path = dir_path + "/data/" + mol + "/lo.txt"; 53 | string K_path = dir_path + "/data/" + mol + "/kappa.txt"; 54 | string L_path = dir_path + "/data/" + mol + "/localocc.txt"; 55 | string H_losc_path = dir_path + "/data/" + mol + "/losc_H_corr.txt"; 56 | LOSCMatrix S = move(test::read_matrices_from_txt(S_path)[0]); 57 | LOSCMatrix C_lo = 58 | move(test::read_matrices_from_txt(C_lo_path)[0].transpose()); 59 | LOSCMatrix K = move(test::read_matrices_from_txt(K_path)[0]); 60 | LOSCMatrix L = move(test::read_matrices_from_txt(L_path)[0]); 61 | LOSCMatrix H_losc_ref = move(test::read_matrices_from_txt(H_losc_path)[0]); 62 | 63 | // Do calculation. 64 | LOSCMatrix H_losc_calc = losc::ao_hamiltonian_correction(S, C_lo, K, L); 65 | 66 | // Testing. 67 | // True condition is the calculated Losc H matrix matches the reference 68 | // to the 8-th digit. 69 | bool status = test::mtx_is_cwise_equal(H_losc_calc, H_losc_ref, 1e-8); 70 | EXPECT_TRUE(status); 71 | if (!status) { 72 | std::ofstream log; 73 | string log_file = "CorrectionTest.losc_H." + mol + ".log"; 74 | log.open(log_file); 75 | log << "data dir path: " << dir_path << std::endl; 76 | log << "H_losc: reference" << std::endl; 77 | test::mtx_show_full(H_losc_ref, log); 78 | log << "H_losc: calculated" << std::endl; 79 | test::mtx_show_full(H_losc_calc, log); 80 | log.close(); 81 | std::cout << "Test Failure: See log file for more information: " 82 | << log_file << std::endl; 83 | } 84 | } 85 | 86 | TEST_P(CorrectionTest, losc_energy_correction) 87 | { 88 | // load data. 89 | string mol = GetParam(); 90 | const char *mol_str = mol.c_str(); 91 | string K_path = dir_path + "/data/" + mol + "/kappa.txt"; 92 | string L_path = dir_path + "/data/" + mol + "/localocc.txt"; 93 | string E_path = dir_path + "/data/" + mol + "/energy.txt"; 94 | LOSCMatrix K = move(test::read_matrices_from_txt(K_path)[0]); 95 | LOSCMatrix L = move(test::read_matrices_from_txt(L_path)[0]); 96 | double E_ref = get_losc_E_correction(E_path); 97 | 98 | // assume it is all RKS calculations. 99 | double E_calc = 2 * losc::energy_correction(K, L); 100 | 101 | // Testing. 102 | // True condition is the calculated total energy correction matches the 103 | // reference to the 8-th digit. 104 | bool status = std::abs(E_calc - E_ref) < 1e-8; 105 | EXPECT_TRUE(status); 106 | if (!status) { 107 | std::ofstream log; 108 | string log_file = "CorrectionTest.losc_energy." + mol + ".log"; 109 | log.open(log_file); 110 | log << "Calculated total energy correction: " << E_calc << std::endl; 111 | log << "Referenced total energy correction: " << E_ref << std::endl; 112 | log.close(); 113 | std::cout << "Test Failure: See log file for more information: " 114 | << log_file << std::endl; 115 | } 116 | } 117 | 118 | TEST_P(CorrectionTest, losc_orbE_projection) 119 | { 120 | // load data. 121 | string mol = GetParam(); 122 | const char *mol_str = mol.c_str(); 123 | string H_dfa_path = dir_path + "/data/" + mol + "/dfa_h.txt"; 124 | string H_losc_path = dir_path + "/data/" + mol + "/losc_H_corr.txt"; 125 | string C_co_path = dir_path + "/data/" + mol + "/lo_basis.txt"; 126 | string eig_path = dir_path + "/data/" + mol + "/losc_eig.txt"; 127 | LOSCMatrix H_dfa = move(test::read_matrices_from_txt(H_dfa_path)[0]); 128 | LOSCMatrix H_losc = move(test::read_matrices_from_txt(H_losc_path)[0]); 129 | LOSCMatrix C_co = test::read_matrices_from_txt(C_co_path)[0].transpose(); 130 | LOSCMatrix eig_ref = move(test::read_matrices_from_txt(eig_path)[0]); 131 | 132 | // Do calculation. 133 | vector eig_calc = 134 | losc::orbital_energy_post_scf(H_dfa, H_losc, C_co); 135 | 136 | // TESTING 137 | // Return is vector, transfer it into matrix to compare. 138 | // True condition is that the calculated eigenvalue matches to 8-th 139 | // digit. 140 | LOSCMatrix eig_calc_M(1, eig_calc.size()); 141 | eig_calc_M.setZero(); 142 | for (size_t i = 0; i < eig_calc.size(); ++i) { 143 | eig_calc_M(0, i) = eig_calc[i]; 144 | } 145 | bool status = test::mtx_is_cwise_equal(eig_calc_M, eig_ref, 1e-8); 146 | EXPECT_TRUE(status); 147 | if (!status) { 148 | std::ofstream log; 149 | string log_file = "CorrectionTest.losc_orbital_energy." + mol + ".log"; 150 | log.open(log_file); 151 | log << "Calculated eig diag:\n"; 152 | test::mtx_show_full(eig_calc_M, log); 153 | log << "Reference eig diag:\n"; 154 | test::mtx_show_full(eig_ref, log); 155 | std::cout << "Test Failure: See log file for more information: " 156 | << log_file << std::endl; 157 | } 158 | } 159 | 160 | INSTANTIATE_TEST_SUITE_P(correction_test, CorrectionTest, 161 | ::testing::Values("H2.1A", "H2.10A", "H2O")); 162 | -------------------------------------------------------------------------------- /tests/losc/curvature_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "matrix_helper.hpp" 11 | #include "matrix_io.hpp" 12 | #include 13 | 14 | using std::string; 15 | using std::vector; 16 | using namespace losc; 17 | 18 | // input matrices data. 19 | typedef struct Data { 20 | string mol; 21 | string df_pmn_path; 22 | string df_Vpq_inv_path; 23 | string grid_basis_value_path; 24 | string grid_weight_path; 25 | string lo_path; 26 | string kappa_ref_path; 27 | 28 | LOSCMatrix df_pmn; 29 | LOSCMatrix df_Vpq_inv; 30 | LOSCMatrix grid_basis_value; 31 | LOSCVector grid_weight; 32 | LOSCMatrix grid_lo; 33 | LOSCMatrix C_lo; 34 | LOSCMatrix kappa_ref; 35 | } Data; 36 | 37 | // load input matrices data from txt file. 38 | static Data load_data(string mol) 39 | { 40 | using std::move; 41 | string file_path = __FILE__; 42 | string dir_path = file_path.substr(0, file_path.rfind("/")); 43 | Data rst; 44 | rst.lo_path = dir_path + "/data/" + mol + "/lo.txt"; 45 | rst.df_pmn_path = dir_path + "/data/" + mol + "/df_pmn.txt"; 46 | rst.df_Vpq_inv_path = dir_path + "/data/" + mol + "/df_Vpq_inv.txt"; 47 | rst.grid_basis_value_path = dir_path + "/data/" + mol + "/grid_basis.txt"; 48 | rst.grid_weight_path = dir_path + "/data/" + mol + "/grid_wt.txt"; 49 | rst.kappa_ref_path = dir_path + "/data/" + mol + "/kappa.txt"; 50 | rst.C_lo = test::read_matrices_from_txt(rst.lo_path)[0].transpose(); 51 | rst.kappa_ref = move(test::read_matrices_from_txt(rst.kappa_ref_path)[0]); 52 | rst.df_pmn = move(test::read_matrices_from_txt(rst.df_pmn_path)[0]); 53 | rst.df_Vpq_inv = move(test::read_matrices_from_txt(rst.df_Vpq_inv_path)[0]); 54 | rst.grid_basis_value = 55 | move(test::read_matrices_from_txt(rst.grid_basis_value_path)[0]); 56 | rst.grid_weight = 57 | move(test::read_matrices_from_txt(rst.grid_weight_path)[0].transpose()); 58 | rst.grid_lo = rst.grid_basis_value * rst.C_lo; 59 | return move(rst); 60 | } 61 | 62 | struct CurvatureTest : public ::testing::TestWithParam { 63 | virtual void SetUp() override {} 64 | virtual void TearDown() override {} 65 | }; 66 | 67 | TEST_P(CurvatureTest, non_block_kappa) 68 | { 69 | // load data. 70 | string mol = GetParam(); 71 | Data data = load_data(mol); 72 | 73 | // calculate df_pii 74 | const size_t nfitbasis = data.df_Vpq_inv.rows(); 75 | const size_t nlo = data.C_lo.cols(); 76 | vector p_index(nfitbasis); 77 | for (size_t i = 0; i < nfitbasis; ++i) { 78 | p_index[i] = i; 79 | } 80 | LOSCMatrix df_pii(nfitbasis, nlo); 81 | losc::utils::convert_df_pmn2pii_blockwise(p_index, data.df_pmn, data.C_lo, 82 | df_pii); 83 | 84 | // Do calculation 85 | losc::DFAInfo b3lyp(0.8, 0.2, "b3lyp"); 86 | losc::CurvatureV2 kappa_man(b3lyp, df_pii, data.df_Vpq_inv, data.grid_lo, 87 | data.grid_weight); 88 | LOSCMatrix kappa_calc = kappa_man.kappa(); 89 | 90 | // Test. 91 | // True consition is that the calculated curvature matrix matches the 92 | // reference to the 8-th digit. 93 | bool status = test::mtx_is_cwise_equal(kappa_calc, data.kappa_ref, 1e-8); 94 | if (!status) { 95 | std::ofstream log; 96 | log.open("CurvatureTest.no_block_kappa." + mol + ".log"); 97 | log << "Kappa matrix: reference\n"; 98 | test::mtx_show_full(data.kappa_ref, log); 99 | log << "Kappa matrix: calculated\n"; 100 | test::mtx_show_full(kappa_calc, log); 101 | log.close(); 102 | } 103 | EXPECT_TRUE(status); 104 | } 105 | 106 | TEST_P(CurvatureTest, block_kappa) 107 | { 108 | // load data. 109 | string mol = GetParam(); 110 | Data data = load_data(mol); 111 | 112 | // calculate df_pii 113 | const size_t nfitbasis = data.df_Vpq_inv.rows(); 114 | const size_t nbasis = data.C_lo.rows(); 115 | const size_t nlo = data.C_lo.cols(); 116 | LOSCMatrix df_pii(nfitbasis, nlo); 117 | const size_t block_size = 3; 118 | size_t nblock = nfitbasis / block_size; 119 | size_t block_tail_size = nfitbasis % block_size; 120 | if (block_tail_size != 0) 121 | nblock++; 122 | for (size_t block_i = 0; block_i < nblock; ++block_i) { 123 | size_t size = block_size; 124 | if (block_i == nblock - 1) { 125 | size = block_tail_size; 126 | } 127 | vector index(size); 128 | for (size_t i = 0; i < size; ++i) { 129 | index[i] = block_i * block_size + i; 130 | } 131 | LOSCMatrix pmn_block = 132 | data.df_pmn.block(index[0], 0, size, nbasis * (nbasis + 1) / 2); 133 | 134 | losc::utils::convert_df_pmn2pii_blockwise(index, pmn_block, data.C_lo, 135 | df_pii); 136 | } 137 | 138 | // Do calculation 139 | losc::DFAInfo b3lyp(0.8, 0.2, "b3lyp"); 140 | losc::CurvatureV2 kappa_man(b3lyp, df_pii, data.df_Vpq_inv, data.grid_lo, 141 | data.grid_weight); 142 | LOSCMatrix kappa_calc = kappa_man.kappa(); 143 | 144 | // Test. 145 | // True consition is that the calculated curvature matrix matches the 146 | // reference to the 8-th digit. 147 | bool status = test::mtx_is_cwise_equal(kappa_calc, data.kappa_ref, 1e-8); 148 | EXPECT_TRUE(status); 149 | if (!status) { 150 | std::ofstream log; 151 | string log_file = "CurvatureTest.block_kappa." + mol + ".log"; 152 | log.open(log_file); 153 | log << "Kappa matrix: reference\n"; 154 | test::mtx_show_full(data.kappa_ref, log); 155 | log << "Kappa matrix: calculated\n"; 156 | test::mtx_show_full(kappa_calc, log); 157 | log.close(); 158 | std::cout << "Test Failure: See log file for more information: " 159 | << log_file << std::endl; 160 | } 161 | } 162 | 163 | INSTANTIATE_TEST_SUITE_P(curvature_test, CurvatureTest, 164 | ::testing::Values("H2.1A", "H2.10A", "H2O")); 165 | -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/ao_overlap.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 9.9999999999999989e-01,6.4589894049923624e-01,9.4137029846174862e-65,3.4750045757814640e-24,6.4589894049923624e-01,9.9999999999999967e-01 3 | 3.4750045757814890e-24,6.2292175305288219e-15,9.4137029846174862e-65,3.4750045757814890e-24,9.9999999999999989e-01,6.4589894049923624e-01 4 | 3.4750045757814640e-24,6.2292175305288219e-15,6.4589894049923624e-01,9.9999999999999967e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/df_Vpq_inv.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 2.6710304865168216e-01,-1.0888137688849760e-01,-7.1476894657409758e-03,6.8587090586033350e-03,-1.0888137688849760e-01,5.7636435237168306e-02 3 | 6.8587090586033333e-03,-6.5814121019172299e-03,-7.1476894657409758e-03,6.8587090586033333e-03,2.6710304865168205e-01,-1.0888137688849757e-01 4 | 6.8587090586033350e-03,-6.5814121019172299e-03,-1.0888137688849757e-01,5.7636435237168306e-02 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/df_pmn.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,10 2 | 4.0862668107032363e+00,2.3678077432215208e+00,2.7426571227990895e+00,4.9365634518654194e-65,1.1135816345697158e-24,2.6220093516504817e-01 3 | 5.0014354854452580e-24,3.2666133233701012e-15,1.6935530622101358e-01,2.6220093516504822e-01,6.7874760275903450e+00,4.2510711535515480e+00 4 | 5.8882567080059642e+00,1.5536222958796018e-64,3.5046359610557749e-24,8.2519215284737391e-01,1.4669037551157473e-23,1.0280523028877218e-14 5 | 5.3299073723240276e-01,8.2519215284737402e-01,2.6220093516504817e-01,1.6935530622101358e-01,2.6220093516504822e-01,4.9365634518654194e-65 6 | 5.0014354854452940e-24,4.0862668107032363e+00,1.1135816345697077e-24,3.2666133233701012e-15,2.3678077432215208e+00,2.7426571227990895e+00 7 | 8.2519215284737391e-01,5.3299073723240276e-01,8.2519215284737402e-01,1.5536222958796018e-64,1.4669037551157579e-23,6.7874760275903450e+00 8 | 3.5046359610557499e-24,1.0280523028877218e-14,4.2510711535515480e+00,5.8882567080059642e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/dfa_density.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 5.5384814505269928e-02,1.2517605185951741e-01,5.5384898910270049e-02,1.2517623863067109e-01,1.2517605185951741e-01,2.8291227657078577e-01 3 | 1.2517624262452703e-01,2.8291269869507796e-01,5.5384898910270049e-02,1.2517624262452703e-01,5.5384983315398796e-02,1.2517642939596535e-01 4 | 1.2517623863067109e-01,2.8291269869507796e-01,1.2517642939596535e-01,2.8291312081999992e-01 5 | Dimension,4,4 6 | 5.5384983501597540e-02,1.2517642981380536e-01,5.5384898910269903e-02,1.2517624262751692e-01,1.2517642981380536e-01,2.8291312175760736e-01 7 | 1.2517623862768021e-01,2.8291269869507640e-01,5.5384898910269903e-02,1.2517623862768021e-01,5.5384814319071468e-02,1.2517605144167768e-01 8 | 1.2517624262751692e-01,2.8291269869507640e-01,1.2517605144167768e-01,2.8291227563317811e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/dfa_h.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 1.4638621908120375e-01,-3.0490824973465902e-01,-3.5466976355800709e-03,-4.1900675314389749e-03,-3.0490824973465902e-01,-1.4879171801854002e-01 3 | -4.1900675325025095e-03,-4.9501445362793838e-03,-3.5466976355800709e-03,-4.1900675325025095e-03,1.4638619849391737e-01,-3.0490826311733649e-01 4 | -4.1900675314389749e-03,-4.9501445362793838e-03,-3.0490826311733649e-01,-1.4879173021689440e-01 5 | Dimension,4,4 6 | 1.4638619847064582e-01,-3.0490826313009967e-01,-3.5466976355800805e-03,-4.1900675325022580e-03,-3.0490826313009967e-01,-1.4879173023215947e-01 7 | -4.1900675314392342e-03,-4.9501445362793769e-03,-3.5466976355800805e-03,-4.1900675314392342e-03,1.4638621910447452e-01,-3.0490824972189390e-01 8 | -4.1900675325022580e-03,-4.9501445362793769e-03,-3.0490824972189390e-01,-1.4879171800327343e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/dipole_ao.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -0.0000000000000000e+00,-0.0000000000000000e+00,8.8946602686276181e-64,1.1937450463130916e-23,-0.0000000000000000e+00,-0.0000000000000000e+00 3 | 5.3730619124383690e-23,5.8857575774348429e-14,8.8946602686276181e-64,5.3730619124383690e-23,1.8897261328856430e+01,1.2205721070645561e+01 4 | 1.1937450463130916e-23,5.8857575774348429e-14,1.2205721070645561e+01,1.8897261328856423e+01 5 | Dimension,4,4 6 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 7 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 8 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 9 | Dimension,4,4 10 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 11 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 12 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/energy.txt: -------------------------------------------------------------------------------- 1 | 0.138322987612635 2 | -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/kappa.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 3.1898014859822843e-01,4.2334172326956306e-02,3.0312566097445176e-01,4.2333000933516322e-02,4.2334172326956306e-02,3.1898014649125883e-01 3 | 4.2333000937575291e-02,3.0312566113582651e-01,3.0312566097445176e-01,4.2333000937575291e-02,2.8805919974955013e-01,4.2141755507028283e-02 4 | 4.2333000933516322e-02,3.0312566113582651e-01,4.2141755507028283e-02,2.8805920195898427e-01 5 | Dimension,4,4 6 | 3.1898014648968365e-01,4.2334172310741013e-02,4.2333000930972503e-02,3.0312566113594847e-01,4.2334172310741013e-02,3.1898014859980517e-01 7 | 3.0312566097433147e-01,4.2333000926907664e-02,4.2333000930972503e-02,3.0312566097433147e-01,2.8805919974789762e-01,4.2141755507239670e-02 8 | 3.0312566113594847e-01,4.2333000926907664e-02,4.2141755507239670e-02,2.8805920196063861e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/lo.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -2.0678808665408610e-10,-4.1261077887710940e-10,-3.3282097350328255e-01,-7.5221366143489388e-01,3.3282096574239428e-01,7.5221366800412515e-01 3 | -2.0685272938969490e-10,-4.1255970861797664e-10,3.6500961106105258e-12,1.1351493174969606e-11,1.2669024560811248e+00,-1.0723741143736967e+00 4 | -1.2669024581199451e+00,1.0723741097657287e+00,3.6391556865270893e-12,1.1298573036537627e-11 5 | Dimension,4,4 6 | 2.0580012694004779e-10,4.1009373674683047e-10,-3.3282096573658221e-01,-7.5221366800904543e-01,3.3282097350909540e-01,7.5221366142997359e-01 7 | 2.0573562298231707e-10,4.1014469598366077e-10,-1.2669024560795978e+00,1.0723741143771486e+00,-4.4339394623341827e-12,-1.0710857877608778e-11 8 | 4.4230066064901300e-12,1.0657956988000526e-11,-1.2669024581214721e+00,1.0723741097622776e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/lo_basis.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -2.3533978521548354e-01,-5.3189498641253030e-01,-2.3534014386712437e-01,-5.3189578003590132e-01,2.3534013837938925e-01,5.3189578468101673e-01 3 | -2.3533979070330185e-01,-5.3189498176734973e-01,5.6018936999384335e-06,-4.7417284854630870e-06,1.2669024560687399e+00,-1.0723741143632135e+00 4 | -1.2669024581075601e+00,1.0723741097552455e+00,5.6018936799829141e-06,-4.7417285587583769e-06 5 | Dimension,4,4 6 | -2.3534014426271932e-01,-5.3189578091728396e-01,-2.3533978481988860e-01,-5.3189498553114611e-01,2.3533979031592689e-01,5.3189498087900733e-01 7 | -2.3534013876676405e-01,-5.3189578556935779e-01,-1.2669024560673074e+00,1.0723741143667453e+00,-5.5804581943836288e-06,4.7235843023677444e-06 8 | 5.5804581744567230e-06,-4.7235843755962254e-06,-1.2669024581091817e+00,1.0723741097518744e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/localocc.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 5.0000075094842689e-01,-4.9999999999943606e-01,0.0000000000000000e+00,0.0000000000000000e+00,-4.9999999999943606e-01,4.9999924905157306e-01 3 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 4 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 5 | Dimension,4,4 6 | 4.9999924739124879e-01,-4.9999999999943362e-01,0.0000000000000000e+00,0.0000000000000000e+00,-4.9999999999943362e-01,5.0000075260875132e-01 7 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 8 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/losc_H_corr.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 4.7496986709718463e-02,-2.1015035455180828e-02,-1.4186789081121289e-02,-1.6760268353662539e-02,-2.1015035455180825e-02,9.2985229412928631e-03 3 | -1.6760268449588341e-02,-1.9800576105577040e-02,-1.4186789081121287e-02,-1.6760268449588341e-02,4.7496664458611781e-02,-2.1015414897842200e-02 4 | -1.6760268353662542e-02,-1.9800576105577044e-02,-2.1015414897842200e-02,9.2980752013269666e-03 5 | Dimension,4,4 6 | 4.7496664102666022e-02,-2.1015415317409795e-02,-1.4186789075687255e-02,-1.6760268443240280e-02,-2.1015415317409795e-02,9.2980747060498539e-03 7 | -1.6760268347171065e-02,-1.9800576097992722e-02,-1.4186789075687253e-02,-1.6760268347171061e-02,4.7496987065664388e-02,-2.1015035035613472e-02 8 | -1.6760268443240276e-02,-1.9800576097992722e-02,-2.1015035035613472e-02,9.2985234365700505e-03 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/losc_eig.txt: -------------------------------------------------------------------------------- 1 | Dimension,1,4 2 | -2.4710290102901541e-01,-1.9418518452958433e-01,1.0363698370631571e+00,1.0363698488760351e+00 3 | Dimension,1,4 4 | -2.4710290102090840e-01,-1.9418518453768971e-01,1.0363698370421046e+00,1.0363698488970843e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/mol.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.3-21G 16 | fitbasis H H.6-31GS 17 | dolosc 18 | end 19 | 20 | $setlosc 21 | print 1 22 | losc_2_2 23 | post 24 | write dipole_ao dipole_ao.bin 25 | write ao_overlap ao_overlap.bin 26 | write dfa_h dfa_h.bin 27 | write dfa_density dfa_density.bin 28 | write df_pmn_matrix df_pmn.bin 29 | write df_Vpq_inverse df_Vpq_inv.bin 30 | write grid_weight grid_wt.bin 31 | write grid_basis_value grid_basis.bin 32 | write lo_coef lo.bin 33 | write umatrix u.bin 34 | write lo_basis_coef lo_basis.bin 35 | write localocc localocc.bin 36 | write losc_eig_proj losc_eig.bin 37 | write kappa kappa.bin 38 | write losc_hamiltonian_correction losc_H_corr.bin 39 | end 40 | 41 | $doqm 42 | -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/mol.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | H2 3 | H 0 0 0 4 | H 10 0 0 5 | -------------------------------------------------------------------------------- /tests/losc/data/H2.10A/u.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 7.0710731218707312e-01,7.0710625018562312e-01,0.0000000000000000e+00,0.0000000000000000e+00,-7.0710625018562312e-01,7.0710731218707312e-01 3 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999022415e-01,4.4217216676297261e-06 4 | 0.0000000000000000e+00,0.0000000000000000e+00,-4.4217216676297261e-06,9.9999999999022415e-01 5 | Dimension,4,4 6 | 7.0710624901159569e-01,7.0710731336109878e-01,0.0000000000000000e+00,0.0000000000000000e+00,-7.0710731336109889e-01,7.0710624901159569e-01 7 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999029887e-01,-4.4048014309789160e-06 8 | 0.0000000000000000e+00,0.0000000000000000e+00,4.4048014309789169e-06,9.9999999999029887e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/ao_overlap.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 9.9999999999999989e-01,6.4589894049923624e-01,1.9994058941565512e-01,3.7638243098570212e-01,6.4589894049923624e-01,9.9999999999999967e-01 3 | 3.7638243098570212e-01,7.2101505826166634e-01,1.9994058941565512e-01,3.7638243098570212e-01,9.9999999999999989e-01,6.4589894049923624e-01 4 | 3.7638243098570212e-01,7.2101505826166634e-01,6.4589894049923624e-01,9.9999999999999967e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/df_Vpq_inv.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 3.1519137902950378e-01,-1.7316260540276557e-01,-1.0721348029588743e-01,9.1092196830196731e-02,-1.7316260540276557e-01,1.7493495819614466e-01 3 | 9.1092196830196717e-02,-1.3583584724659570e-01,-1.0721348029588743e-01,9.1092196830196717e-02,3.1519137902950384e-01,-1.7316260540276557e-01 4 | 9.1092196830196731e-02,-1.3583584724659570e-01,-1.7316260540276557e-01,1.7493495819614466e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/df_pmn.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,10 2 | 4.0862668107032363e+00,2.3678077432215208e+00,2.7426571227990895e+00,6.8765387377938247e-01,1.0099135491871332e+00,2.4670291229982575e+00 3 | 1.3562799708352264e+00,1.8436454094914130e+00,1.5488750708451287e+00,2.1216810105972690e+00,6.7874760275903450e+00,4.2510711535515480e+00 4 | 5.8882567080059642e+00,1.2925969271593702e+00,2.2213817051513374e+00,5.7545719875322892e+00,2.4636816810260722e+00,4.1081835209713384e+00 5 | 3.6374751004145662e+00,5.1892027116078943e+00,2.4670291229982575e+00,1.5488750708451291e+00,2.1216810105972690e+00,6.8765387377938247e-01 6 | 1.3562799708352264e+00,4.0862668107032363e+00,1.0099135491871334e+00,1.8436454094914130e+00,2.3678077432215208e+00,2.7426571227990895e+00 7 | 5.7545719875322892e+00,3.6374751004145662e+00,5.1892027116078943e+00,1.2925969271593702e+00,2.4636816810260722e+00,6.7874760275903450e+00 8 | 2.2213817051513374e+00,4.1081835209713384e+00,4.2510711535515480e+00,5.8882567080059642e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/dfa_density.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 7.0624933298660944e-02,9.5164138140597140e-02,7.0624933298661596e-02,9.5164138140599042e-02,9.5164138140597140e-02,1.2822968837004708e-01 3 | 9.5164138140598015e-02,1.2822968837004964e-01,7.0624933298661596e-02,9.5164138140598015e-02,7.0624933298662249e-02,9.5164138140599916e-02 4 | 9.5164138140599042e-02,1.2822968837004964e-01,9.5164138140599916e-02,1.2822968837005222e-01 5 | Dimension,4,4 6 | 7.0624933298660944e-02,9.5164138140597140e-02,7.0624933298661596e-02,9.5164138140599042e-02,9.5164138140597140e-02,1.2822968837004708e-01 7 | 9.5164138140598015e-02,1.2822968837004964e-01,7.0624933298661596e-02,9.5164138140598015e-02,7.0624933298662249e-02,9.5164138140599916e-02 8 | 9.5164138140599042e-02,1.2822968837004964e-01,9.5164138140599916e-02,1.2822968837005222e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/dfa_h.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 1.2925744662857686e-01,-3.4282930665410932e-01,-2.6871177529769441e-01,-2.8651223560173344e-01,-3.4282930665410932e-01,-2.2977038037630465e-01 3 | -2.8651223560173511e-01,-2.5319339856326428e-01,-2.6871177529769441e-01,-2.8651223560173511e-01,1.2925744662857525e-01,-3.4282930665411104e-01 4 | -2.8651223560173344e-01,-2.5319339856326428e-01,-3.4282930665411104e-01,-2.2977038037630704e-01 5 | Dimension,4,4 6 | 1.2925744662857686e-01,-3.4282930665410932e-01,-2.6871177529769441e-01,-2.8651223560173344e-01,-3.4282930665410932e-01,-2.2977038037630465e-01 7 | -2.8651223560173511e-01,-2.5319339856326428e-01,-2.6871177529769441e-01,-2.8651223560173511e-01,1.2925744662857525e-01,-3.4282930665411104e-01 8 | -2.8651223560173344e-01,-2.5319339856326428e-01,-3.4282930665411104e-01,-2.2977038037630704e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/dipole_ao.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -0.0000000000000000e+00,-0.0000000000000000e+00,1.8891647842166107e-01,1.2434871600212673e-01,-0.0000000000000000e+00,-0.0000000000000000e+00 3 | 5.8691099979058170e-01,6.8126049890056772e-01,1.8891647842166107e-01,5.8691099979058170e-01,1.8897261328856430e+00,1.2205721070645563e+00 4 | 1.2434871600212673e-01,6.8126049890056772e-01,1.2205721070645563e+00,1.8897261328856425e+00 5 | Dimension,4,4 6 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 7 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 8 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 9 | Dimension,4,4 10 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 11 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 12 | -0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00,-0.0000000000000000e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/energy.txt: -------------------------------------------------------------------------------- 1 | 0.000000000000000 2 | -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/kappa.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 2.9705948097806389e-01,2.3956635761578471e-01,2.4817599380624217e-01,2.5712161041289527e-01,2.3956635761578471e-01,1.9320049813704521e-01 3 | 2.0014381863216599e-01,2.0735809363199811e-01,2.4817599380624217e-01,2.0014381863216599e-01,2.0733667109000337e-01,2.1481021572913137e-01 4 | 2.5712161041289527e-01,2.0735809363199811e-01,2.1481021572913137e-01,2.2255314768493328e-01 5 | Dimension,4,4 6 | 2.9705948097806389e-01,2.3956635761578471e-01,2.4817599380624217e-01,2.5712161041289527e-01,2.3956635761578471e-01,1.9320049813704521e-01 7 | 2.0014381863216599e-01,2.0735809363199811e-01,2.4817599380624217e-01,2.0014381863216599e-01,2.0733667109000337e-01,2.1481021572913137e-01 8 | 2.5712161041289527e-01,2.0735809363199811e-01,2.1481021572913137e-01,2.2255314768493328e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/lo.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -2.6575351982365342e-01,-3.5809173178118353e-01,-2.6575351982365586e-01,-3.5809173178119069e-01,-2.0369179864498821e-01,-1.1116360720061578e+00 3 | 2.0369179864498163e-01,1.1116360720061587e+00,8.7918318399415729e-01,-6.7819159017609876e-01,8.7918318399417139e-01,-6.7819159017611019e-01 4 | 9.4072708978406661e-01,-1.1921055991293616e+00,-9.4072708978405395e-01,1.1921055991293521e+00 5 | Dimension,4,4 6 | -2.6575351982365342e-01,-3.5809173178118353e-01,-2.6575351982365586e-01,-3.5809173178119069e-01,-2.0369179864498821e-01,-1.1116360720061578e+00 7 | 2.0369179864498163e-01,1.1116360720061587e+00,8.7918318399415729e-01,-6.7819159017609876e-01,8.7918318399417139e-01,-6.7819159017611019e-01 8 | 9.4072708978406661e-01,-1.1921055991293616e+00,-9.4072708978405395e-01,1.1921055991293521e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/lo_basis.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -2.6575351982365342e-01,-3.5809173178118353e-01,-2.6575351982365586e-01,-3.5809173178119069e-01,-2.0369179864498821e-01,-1.1116360720061578e+00 3 | 2.0369179864498163e-01,1.1116360720061587e+00,8.7918318399415729e-01,-6.7819159017609876e-01,8.7918318399417139e-01,-6.7819159017611019e-01 4 | 9.4072708978406661e-01,-1.1921055991293616e+00,-9.4072708978405395e-01,1.1921055991293521e+00 5 | Dimension,4,4 6 | -2.6575351982365342e-01,-3.5809173178118353e-01,-2.6575351982365586e-01,-3.5809173178119069e-01,-2.0369179864498821e-01,-1.1116360720061578e+00 7 | 2.0369179864498163e-01,1.1116360720061587e+00,8.7918318399415729e-01,-6.7819159017609876e-01,8.7918318399417139e-01,-6.7819159017611019e-01 8 | 9.4072708978406661e-01,-1.1921055991293616e+00,-9.4072708978405395e-01,1.1921055991293521e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/localocc.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 3 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 4 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 5 | Dimension,4,4 6 | 1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 7 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 8 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/losc_H_corr.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | -1.4751905182167950e-02,-8.7883843566255671e-02,-9.7499164383799838e-02,-1.1291849467018653e-01,-8.7883843566255671e-02,-9.6075559166535013e-02 3 | -1.1291849467018690e-01,-1.2320894032311276e-01,-9.7499164383799825e-02,-1.1291849467018690e-01,-1.4751905182169282e-02,-8.7883843566256920e-02 4 | -1.1291849467018653e-01,-1.2320894032311275e-01,-8.7883843566256920e-02,-9.6075559166536179e-02 5 | Dimension,4,4 6 | -1.4751905182167950e-02,-8.7883843566255671e-02,-9.7499164383799838e-02,-1.1291849467018653e-01,-8.7883843566255671e-02,-9.6075559166535013e-02 7 | -1.1291849467018690e-01,-1.2320894032311276e-01,-9.7499164383799825e-02,-1.1291849467018690e-01,-1.4751905182169282e-02,-8.7883843566256920e-02 8 | -1.1291849467018653e-01,-1.2320894032311275e-01,-8.7883843566256920e-02,-9.6075559166536179e-02 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/losc_eig.txt: -------------------------------------------------------------------------------- 1 | Dimension,1,4 2 | -5.3165121740425947e-01,1.3650553124574749e-01,9.4480108278784236e-01,1.1348560585815313e+00 3 | Dimension,1,4 4 | -5.3165121740425947e-01,1.3650553124574749e-01,9.4480108278784236e-01,1.1348560585815313e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/mol.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.3-21G 16 | fitbasis H H.6-31GS 17 | dolosc 18 | end 19 | 20 | $setlosc 21 | print 1 22 | losc_2_2 23 | post 24 | write dipole_ao dipole_ao.bin 25 | write ao_overlap ao_overlap.bin 26 | write dfa_h dfa_h.bin 27 | write dfa_density dfa_density.bin 28 | write df_pmn_matrix df_pmn.bin 29 | write df_Vpq_inverse df_Vpq_inv.bin 30 | write grid_weight grid_wt.bin 31 | write grid_basis_value grid_basis.bin 32 | write lo_coef lo.bin 33 | write lo_basis_coef lo_basis.bin 34 | write umatrix u.bin 35 | write localocc localocc.bin 36 | write losc_eig_proj losc_eig.bin 37 | write kappa kappa.bin 38 | write losc_hamiltonian_correction losc_H_corr.bin 39 | end 40 | 41 | $doqm 42 | -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/mol.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | H2 3 | H 0 0 0 4 | H 1 0 0 5 | -------------------------------------------------------------------------------- /tests/losc/data/H2.1A/u.txt: -------------------------------------------------------------------------------- 1 | Dimension,4,4 2 | 1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00 3 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00,0.0000000000000000e+00 4 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00 5 | Dimension,4,4 6 | 1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00 7 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00,0.0000000000000000e+00 8 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/ao_overlap.txt: -------------------------------------------------------------------------------- 1 | Dimension,13,13 2 | 9.9999999999999978e-01,2.3368990605916301e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.6727975959589536e-01 3 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,2.9294188196789656e-02,6.5837185110395172e-02,2.9294188196789656e-02 4 | 6.5837185110395172e-02,2.3368990605916301e-01,9.9999999999999978e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 5 | 7.6364077333844393e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,2.2052961381103270e-01,3.6513421454584161e-01 6 | 2.2052961381103270e-01,3.6513421454584161e-01,0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999999978e-01,0.0000000000000000e+00 7 | 0.0000000000000000e+00,0.0000000000000000e+00,5.0152064107481087e-01,0.0000000000000000e+00,0.0000000000000000e+00,2.6262518537398694e-01 8 | 1.4801363312390087e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 9 | 9.9999999999999978e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,5.0152064107481087e-01,0.0000000000000000e+00 10 | 0.0000000000000000e+00,0.0000000000000000e+00,2.6262518537398694e-01,1.4801363312390087e-01,0.0000000000000000e+00,0.0000000000000000e+00 11 | 0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999999978e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 12 | 5.0152064107481087e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.6727975959589536e-01 13 | 7.6364077333844393e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000002e+00,0.0000000000000000e+00 14 | 0.0000000000000000e+00,0.0000000000000000e+00,4.0341813550694333e-01,6.6377416263792377e-01,4.0341813550694333e-01,6.6377416263792377e-01 15 | 0.0000000000000000e+00,0.0000000000000000e+00,5.0152064107481087e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 16 | 9.9999999999999989e-01,0.0000000000000000e+00,0.0000000000000000e+00,5.7502836769124599e-01,4.8746944775779155e-01,0.0000000000000000e+00 17 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,5.0152064107481087e-01,0.0000000000000000e+00 18 | 0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999999989e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 19 | 5.7502836769124599e-01,4.8746944775779155e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00 20 | 5.0152064107481087e-01,0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,9.9999999999999989e-01,0.0000000000000000e+00 21 | 0.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,2.9294188196789656e-02,2.2052961381103270e-01,2.6262518537398694e-01 22 | 0.0000000000000000e+00,0.0000000000000000e+00,4.0341813550694333e-01,5.7502836769124599e-01,0.0000000000000000e+00,0.0000000000000000e+00 23 | 9.9999999999999978e-01,6.5829204933932972e-01,7.3759277426864528e-02,2.5768183431112235e-01,6.5837185110395172e-02,3.6513421454584161e-01 24 | 1.4801363312390087e-01,0.0000000000000000e+00,0.0000000000000000e+00,6.6377416263792377e-01,4.8746944775779155e-01,0.0000000000000000e+00 25 | 0.0000000000000000e+00,6.5829204933932972e-01,9.9999999999999989e-01,2.5768183431112235e-01,5.6217983799476390e-01,2.9294188196789656e-02 26 | 2.2052961381103270e-01,0.0000000000000000e+00,2.6262518537398694e-01,0.0000000000000000e+00,4.0341813550694333e-01,0.0000000000000000e+00 27 | 5.7502836769124599e-01,0.0000000000000000e+00,7.3759277426864528e-02,2.5768183431112235e-01,9.9999999999999978e-01,6.5829204933932972e-01 28 | 6.5837185110395172e-02,3.6513421454584161e-01,0.0000000000000000e+00,1.4801363312390087e-01,0.0000000000000000e+00,6.6377416263792377e-01 29 | 0.0000000000000000e+00,4.8746944775779155e-01,0.0000000000000000e+00,2.5768183431112235e-01,5.6217983799476390e-01,6.5829204933932972e-01 30 | 9.9999999999999989e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2O/energy.txt: -------------------------------------------------------------------------------- 1 | 0.000000239608568 2 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/gamma=0.win=0_7.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.6-31G 16 | basis O O.6-31G 17 | fitbasis H H.6-31GSS 18 | fitbasis O O.6-31GSS 19 | dolosc 20 | end 21 | 22 | $setlosc 23 | print 1 24 | losc_2_2 gamma 0 25 | post 26 | localize window index 0 7 27 | write lo_coef lo.gamma=0.win=0_7.bin 28 | write lo_basis_coef lo_basis.gamma=0.win=0_7.bin 29 | write umatrix u.gamma=0.win=0_7.bin 30 | 31 | end 32 | 33 | $doqm 34 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/gamma=0.win=5_7.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.6-31G 16 | basis O O.6-31G 17 | fitbasis H H.6-31GSS 18 | fitbasis O O.6-31GSS 19 | dolosc 20 | end 21 | 22 | $setlosc 23 | print 1 24 | losc_2_2 gamma 0 25 | post 26 | localize window index 5 7 27 | write lo_coef lo.gamma=0.win=5_7.bin 28 | write lo_basis_coef lo_basis.gamma=0.win=5_7.bin 29 | write umatrix u.gamma=0.win=5_7.bin 30 | 31 | end 32 | 33 | $doqm 34 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/gamma=0.win=all.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.6-31G 16 | basis O O.6-31G 17 | fitbasis H H.6-31GSS 18 | fitbasis O O.6-31GSS 19 | dolosc 20 | end 21 | 22 | $setlosc 23 | print 1 24 | losc_2_2 gamma 0 25 | post 26 | write lo_coef lo.gamma=0.win=all.bin 27 | write lo_basis_coef lo_basis.gamma=0.win=all.bin 28 | write umatrix u.gamma=0.win=all.bin 29 | 30 | end 31 | 32 | $doqm 33 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/gamma=default.win=0_7.inp: -------------------------------------------------------------------------------- 1 | $qm 2 | xyz mol.xyz 3 | spin 2 4 | charge 0 5 | mult 1 6 | method dft 7 | xcfunc b3lyp 8 | guess atom 9 | iter 300 10 | dentol 1.0E-004 11 | etol 1.0E-008 12 | print 1 13 | diis 12 0.30 14 | directvee 15 | basis H H.6-31G 16 | basis O O.6-31G 17 | fitbasis H H.6-31GSS 18 | fitbasis O O.6-31GSS 19 | dolosc 20 | end 21 | 22 | $setlosc 23 | print 1 24 | losc_2_2 25 | post 26 | localize window index 0 7 27 | write lo_coef lo.gamma=default.win=0_7.bin 28 | write lo_basis_coef lo_basis.gamma=default.win=0_7.bin 29 | write umatrix u.gamma=default.win=0_7.bin 30 | end 31 | 32 | $doqm 33 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo.gamma=0.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,13 2 | 1.0121458410264081e+00,-1.8304291326343015e-02,2.6710624194686877e-03,2.6710786582431361e-03,6.6182438022621197e-08,-7.4448828520821270e-02 3 | -2.3373603726188955e-03,-2.3373461684620075e-03,5.0953512646993667e-08,-4.4201489519292234e-03,1.7255859117216298e-02,-4.4201436903646288e-03 4 | 1.7255842972295907e-02,3.8179692315200811e-02,-6.7451864394617048e-02,-9.8786663466028296e-02,3.4239868095670589e-02,6.6781147458878774e-08 5 | -6.4786730765915457e-01,-3.9422006480077565e-01,9.9430684938545427e-02,5.0072990773944901e-08,2.9879021784102100e-01,1.4138370884925626e+00 6 | -4.2081708385301092e-02,-2.3528139323785727e-01,-3.8179694697891758e-02,6.7451872398359175e-02,-3.4239904445843176e-02,9.8786681733041698e-02 7 | -2.6961881540385052e-08,6.4786731129318675e-01,-9.9430721540934131e-02,3.9422008641437228e-01,-2.0205269246837393e-08,4.2081705538072556e-02 8 | 2.3528142696154813e-01,-2.9879019702910831e-01,-1.4138371242147292e+00,-6.7370624663343398e-02,2.5429089299343799e-01,-2.2919968052384512e-01 9 | -2.2919666915111334e-01,4.5929934197733274e-01,2.1924192406126455e-01,-1.8748058212872967e-01,-1.8747806997440722e-01,3.5454861351462130e-01 10 | -3.8972452127041826e-02,7.7973269412292198e-02,-3.8971407278423971e-02,7.7970608431469815e-02,-6.7370353131493990e-02,2.5429047527517612e-01 11 | -2.2919770044511154e-01,-2.2919898647716391e-01,-4.5929952626135256e-01,2.1924119877302886e-01,-1.8747894883871213e-01,-1.8748001964044836e-01 12 | -3.5454874760648047e-01,-3.8971787719843914e-02,7.7971700607140121e-02,-3.8972226876914963e-02,7.7972822527229521e-02,8.1367214049791026e-02 13 | -2.6766922991712799e-01,1.1241134597087309e-01,-5.5138389677430633e-01,1.7464062001258885e-06,-4.4233904260095208e-01,9.7277053281113579e-02 14 | -4.6375050392946204e-01,1.3505970399456479e-06,8.9301026640962299e-03,-9.7085609965807368e-02,-2.1630407591590359e-01,5.1054713769220050e-01 15 | -8.1367256107459984e-02,2.6766952818190365e-01,5.5138345812516720e-01,-1.1241269829554576e-01,1.2270704538931922e-06,4.4233906286324315e-01 16 | 4.6375015971642281e-01,-9.7278165208142600e-02,9.4971095395405505e-07,2.1630398092001862e-01,-5.1054712659835499e-01,-8.9305153256205028e-03 17 | 9.7086466596899401e-02 18 | Dimension,7,13 19 | 1.0121458423281375e+00,-1.8304297526147404e-02,2.6710784703224545e-03,2.6710868617523861e-03,9.9559775393014199e-09,-7.4448825078245157e-02 20 | -2.3373460355404930e-03,-2.3373380172471087e-03,7.5504166409594695e-09,-4.4201459479158156e-03,1.7255844585824340e-02,-4.4201438012333180e-03 21 | 1.7255833835136739e-02,3.8179698274781924e-02,-6.7451869346638160e-02,-9.8786668174099077e-02,3.4239877673815339e-02,1.0498465942376372e-08 22 | -6.4786730908152823e-01,-3.9422006940093474e-01,9.9430695217751552e-02,6.6264958772807931e-09,2.9879021586226601e-01,1.4138370964113141e+00 23 | -4.2081708356724597e-02,-2.3528140963443633e-01,-3.8179701874627520e-02,6.7451876363818816e-02,-3.4239899890889748e-02,9.8786676832210360e-02 24 | 6.0756227421166724e-09,6.4786732060571062e-01,-9.9430715346014331e-02,3.9422008181252099e-01,5.2974916140046713e-09,4.2081705116258417e-02 25 | 2.3528141195657101e-01,-2.9879019781922761e-01,-1.4138371193261190e+00,-6.7370496781411590e-02,2.5429072873323327e-01,-2.2919867660210108e-01 26 | -2.2919743673364143e-01,4.5929960318747393e-01,2.1924170520776498e-01,-1.8747975604466824e-01,-1.8747872999249979e-01,3.5454881515151870e-01 27 | -3.8972114429995063e-02,7.7972510206447132e-02,-3.8971681956084581e-02,7.7971426211027331e-02,-6.7370445821512859e-02,2.5429065710315690e-01 28 | -2.2919827502883616e-01,-2.2919861698833216e-01,-4.5929926505538088e-01,2.1924143296794110e-01,-1.8747941657016601e-01,-1.8747969761190106e-01 29 | -3.5454854597280705e-01,-3.8971973178390670e-02,7.7972085587893800e-02,-3.8972083744382054e-02,7.7972375975654928e-02,8.1367227105883941e-02 30 | -2.6766929142304258e-01,1.1241166224390357e-01,-5.5138379949269778e-01,7.6898249454997890e-07,-4.4233903197667757e-01,9.7277314205613488e-02 31 | -4.6375042671067956e-01,5.9609080691492465e-07,8.9301990479834295e-03,-9.7085815263495231e-02,-2.1630405523774970e-01,5.1054712732132779e-01 32 | -8.1367249833379215e-02,2.6766944731535802e-01,5.5138357147616646e-01,-1.1241236499215375e-01,3.2084992255244627e-07,4.4233905074061169e-01 33 | 4.6375024734650849e-01,-9.7277890285881866e-02,2.5016884383415763e-07,2.1630400724729829e-01,-5.1054713018988307e-01,-8.9304157756171301e-03 34 | 9.7086256083979583e-02 -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo.gamma=0.win=5_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,2,13 2 | 5.6977458466489377e-02,-1.0014601150355290e-01,-3.8413159820451515e-01,4.8281025277157136e-02,1.6802359852616382e-09,-6.9344580030002512e-01 3 | -5.9723677767409877e-01,1.0368113505852777e-01,-2.0862873163423826e-10,1.6210586270944694e-01,1.4934113528403277e+00,-3.0836959755171645e-02 4 | -2.4639226550273108e-01,5.6977459257672530e-02,-1.0014601474213584e-01,4.8281026817883793e-02,-3.8413158717334644e-01,1.8831347309860931e-08 5 | -6.9344580160535074e-01,1.0368114252298080e-01,-5.9723677742640380e-01,1.6163082381824893e-08,-3.0836968325756442e-02,-2.4639226628762245e-01 6 | 1.6210585926736720e-01,1.4934113617007452e+00 7 | Dimension,2,13 8 | 5.6977458466489682e-02,-1.0014601150355069e-01,-3.8413159820451498e-01,4.8281025277153944e-02,1.6802357465976431e-09,-6.9344580030003566e-01 9 | -5.9723677767409944e-01,1.0368113505852156e-01,-2.0862889767421089e-10,1.6210586270944766e-01,1.4934113528403272e+00,-3.0836959755169965e-02 10 | -2.4639226550271731e-01,5.6977459257671656e-02,-1.0014601474212868e-01,4.8281026817887290e-02,-3.8413158717334617e-01,1.8831347386997710e-08 11 | -6.9344580160535441e-01,1.0368114252298327e-01,-5.9723677742640846e-01,1.6163082381900260e-08,-3.0836968325756164e-02,-2.4639226628763333e-01 12 | 1.6210585926736815e-01,1.4934113617007516e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo.gamma=default.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,13 2 | 9.9506070196129726e-01,2.7752979639959870e-02,1.6017216781758618e-03,1.6017215114187029e-03,-2.0283218379817088e-10,-1.2819784498827615e-02 3 | -2.1780200663635649e-03,-2.1780199812887900e-03,7.5563066556113766e-11,3.8695962122241057e-04,2.7975359182489399e-03,3.8695962874405756e-04 4 | 2.7975358593721441e-03,-2.0782743734232181e-01,4.6157312104692838e-01,1.1273919233985678e-01,1.1273917500509519e-01,-4.7658647583534962e-09 5 | 4.5387311662836299e-01,5.4820113978271294e-02,5.4820104834253439e-02,-1.4883399280655090e-09,1.4698885788272309e-01,1.6119437873840371e-03 6 | 1.4698884249520644e-01,1.6119405597152798e-03,8.5040246868172946e-09,-1.9192800024069379e-08,3.6852960361749826e-01,-3.6852959113211287e-01 7 | -3.3205491475215028e-09,-2.7450082181869416e-08,1.8356194006255971e-01,-1.8356193460600259e-01,2.4533231710154741e-10,2.5456663832272414e-01 8 | 1.7512997838773475e-01,-2.5456662606573882e-01,-1.7512996723900165e-01,-9.9003690936833158e-02,2.1913194746106349e-01,-3.6722706457573079e-01 9 | -3.6722709143687443e-01,-2.4372885830269847e-08,4.0312195698552333e-01,-2.3777415399151150e-01,-2.3777417421314737e-01,-1.3277709669734303e-08 10 | -1.6493697458341597e-01,-1.1968408522944894e-01,-1.6493697894727261e-01,-1.1968408609248682e-01,5.9366499233446256e-09,-1.2423087142195945e-08 11 | 1.1170620435423701e-08,-4.6498800225852882e-09,-6.4954748892538861e-01,-3.6374590282731261e-08,9.7618677799409537e-09,-2.4078531611250373e-09 12 | -5.0140755257294956e-01,9.4473659799671160e-10,1.3611340614391498e-09,1.1265198020470671e-08,4.3511308073462371e-08,8.0830846944302356e-02 13 | -1.4218673942376675e-01,-2.3650293177880236e-01,-2.3650279183344208e-01,1.4568369273915852e-08,-9.8173095296871526e-01,-3.4836412750442841e-01 14 | -3.4836391664035027e-01,1.1316700982699230e-08,9.3266555091754064e-02,8.8209672132512118e-01,9.3266499248391657e-02,8.8209619211630530e-01 15 | 1.8137369429999297e-08,-3.3196469370326096e-08,3.0552627564114027e-01,-3.0552637000041466e-01,1.2129795899316216e-08,-2.1466730112335638e-07 16 | 4.9550647185523067e-01,-4.9550661831371551e-01,1.1576395912711668e-08,-1.3659395954355802e-01,-1.2303389729635188e+00,1.3659399158729868e-01 17 | 1.2303393629272150e+00 18 | Dimension,7,13 19 | 9.9506070196129726e-01,2.7752979639959863e-02,1.6017216781758637e-03,1.6017215114186979e-03,-2.0283218333886336e-10,-1.2819784498827596e-02 20 | -2.1780200663635728e-03,-2.1780199812887696e-03,7.5563066365961073e-11,3.8695962122240661e-04,2.7975359182489594e-03,3.8695962874406650e-04 21 | 2.7975358593720964e-03,-2.0782743650276136e-01,4.6157311918866883e-01,1.1273919545397705e-01,1.1273917811921563e-01,-4.7658645058387421e-09 22 | 4.5387311320985224e-01,5.4820115994618696e-02,5.4820106850601465e-02,-1.4883397980949855e-09,1.4698885928140412e-01,1.6119448023160761e-03 23 | 1.4698884389388758e-01,1.6119415746463403e-03,8.5040247782899194e-09,-1.9192800515210974e-08,3.6852960361749870e-01,-3.6852959113211281e-01 24 | -3.3205489776866460e-09,-2.7450081817206886e-08,1.8356194006256038e-01,-1.8356193460600220e-01,2.4533249218005430e-10,2.5456663832272453e-01 25 | 1.7512997838773459e-01,-2.5456662606573882e-01,-1.7512996723900220e-01,-9.9003692699229609e-02,2.1913195137524755e-01,-3.6722706361969182e-01 26 | -3.6722709048083596e-01,-2.4372886234532097e-08,4.0312196083441160e-01,-2.3777415352663128e-01,-2.3777417374826709e-01,-1.3277709852155362e-08 27 | -1.6493697333693702e-01,-1.1968408521577974e-01,-1.6493697770079374e-01,-1.1968408607881940e-01,5.9366499248054274e-09,-1.2423087108472835e-08 28 | 1.1170620718300573e-08,-4.6498792558713634e-09,-6.4954748892538838e-01,-3.6374590429263097e-08,9.7618679448025315e-09,-2.4078537050400252e-09 29 | -5.0140755257294944e-01,9.4473731023400340e-10,1.3611329271141683e-09,1.1265196960665544e-08,4.3511309585332292e-08,8.0830846944301954e-02 30 | -1.4218673942376014e-01,-2.3650293177879975e-01,-2.3650279183344414e-01,1.4568369160666275e-08,-9.8173095296872526e-01,-3.4836412750442713e-01 31 | -3.4836391664035798e-01,1.1316700865795576e-08,9.3266555091754744e-02,8.8209672132511308e-01,9.3266499248393503e-02,8.8209619211631951e-01 32 | 1.8137368594318018e-08,-3.3196465871375716e-08,3.0552627564114260e-01,-3.0552637000041222e-01,1.2129796122512514e-08,-2.1466729625429034e-07 33 | 4.9550647185523289e-01,-4.9550661831371440e-01,1.1576396030061005e-08,-1.3659395954355832e-01,-1.2303389729635261e+00,1.3659399158729815e-01 34 | 1.2303393629272097e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo_basis.gamma=0.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,13 2 | 9.9506069514886897e-01,2.7752992978578334e-02,1.6017309470001567e-03,1.6017307802393154e-03,-2.0283313890168198e-10,-1.2819729509628746e-02 3 | -2.1780049140020250e-03,-2.1780048289320592e-03,7.5562395788579339e-11,3.8695521681722788e-04,2.7974927276545147e-03,3.8695522433982522e-04 4 | 2.7974926687892279e-03,-2.0786668994193805e-01,4.6166177720994850e-01,1.1256728501554372e-01,1.1256726767252316e-01,-4.7757910652874364e-09 5 | 4.5400098553642732e-01,5.4699248244083613e-02,5.4699239096071120e-02,-1.4935821067139812e-09,1.4692140639053922e-01,1.6028888823126088e-03 6 | 1.4692139099989870e-01,1.6028856419927303e-03,8.4984678322252589e-09,-1.9182198428644086e-08,3.6833417743180247e-01,-3.6833416492144222e-01 7 | -3.3283041534110201e-09,-2.7386200114322805e-08,1.8324507999690512e-01,-1.8324507449878205e-01,2.3793042119106210e-10,2.5465392328028974e-01 8 | 1.7591661066678344e-01,-2.5465391102985296e-01,-1.7591659963552667e-01,-9.9127148059990122e-02,2.1930704542540574e-01,-3.6664731118114940e-01 9 | -3.6664733821644929e-01,-2.4409379045697059e-08,4.0552771920388986e-01,-2.3687273601639566e-01,-2.3687275648611478e-01,-1.3307044183361742e-08 10 | -1.6524803696593174e-01,-1.2202524950678661e-01,-1.6524804125961159e-01,-1.2202524972737973e-01,5.9366499233446256e-09,-1.2423087142195945e-08 11 | 1.1170620435423701e-08,-4.6498800225852882e-09,-6.4954748892538861e-01,-3.6374590282731261e-08,9.7618677799409537e-09,-2.4078531611250373e-09 12 | -5.0140755257294956e-01,9.4473659799671160e-10,1.3611340614391498e-09,1.1265198020470671e-08,4.3511308073462371e-08,8.0578295072309514e-02 13 | -1.4162784997591951e-01,-2.3748224735853374e-01,-2.3748217891643625e-01,1.4503878416605176e-08,-9.8068045647795987e-01,-3.4899658653980259e-01 14 | -3.4899649157959117e-01,1.1281501197561282e-08,9.2821139149852974e-02,8.8177577655788364e-01,9.2821115231684168e-02,8.8177553500331440e-01 15 | 8.6935683007728097e-09,-1.6586895679683905e-08,3.0576187545095368e-01,-3.0576191450739826e-01,1.2127668586629059e-08,-9.9919513311105213e-08 16 | 4.9562377919645634e-01,-4.9562384420327971e-01,1.1576549086785098e-08,-1.3643117483633058e-01,-1.2302268480058749e+00,1.3643118508207699e-01 17 | 1.2302270317409145e+00 18 | Dimension,7,13 19 | 9.9506069514886897e-01,2.7752992978578327e-02,1.6017309470001586e-03,1.6017307802393104e-03,-2.0283313844237175e-10,-1.2819729509628727e-02 20 | -2.1780049140020328e-03,-2.1780048289320388e-03,7.5562395598430950e-11,3.8695521681722392e-04,2.7974927276545342e-03,3.8695522433983417e-04 21 | 2.7974926687891802e-03,-2.0786668994193827e-01,4.6166177720994866e-01,1.1256728501554367e-01,1.1256726767252304e-01,-4.7757910196214591e-09 22 | 4.5400098553642904e-01,5.4699248244083634e-02,5.4699239096071599e-02,-1.4935820894195499e-09,1.4692140639053905e-01,1.6028888823122528e-03 23 | 1.4692139099989865e-01,1.6028856419913885e-03,8.4984679242321928e-09,-1.9182198922022779e-08,3.6833417743180291e-01,-3.6833416492144216e-01 24 | -3.3283039837189078e-09,-2.7386199752773587e-08,1.8324507999690579e-01,-1.8324507449878166e-01,2.3793059619450106e-10,2.5465392328029013e-01 25 | 1.7591661066678327e-01,-2.5465391102985296e-01,-1.7591659963552722e-01,-9.9127148059990206e-02,2.1930704542540597e-01,-3.6664731118114952e-01 26 | -3.6664733821644974e-01,-2.4409379409262470e-08,4.0552771920389108e-01,-2.3687273601639522e-01,-2.3687275648611422e-01,-1.3307044352858269e-08 27 | -1.6524803696593224e-01,-1.2202524950678682e-01,-1.6524804125961209e-01,-1.2202524972738175e-01,5.9366499248054274e-09,-1.2423087108472835e-08 28 | 1.1170620718300573e-08,-4.6498792558713634e-09,-6.4954748892538838e-01,-3.6374590429263097e-08,9.7618679448025315e-09,-2.4078537050400252e-09 29 | -5.0140755257294944e-01,9.4473731023400340e-10,1.3611329271141683e-09,1.1265196960665544e-08,4.3511309585332292e-08,8.0578295072309111e-02 30 | -1.4162784997591291e-01,-2.3748224735853113e-01,-2.3748217891643830e-01,1.4503878302388163e-08,-9.8068045647796986e-01,-3.4899658653980126e-01 31 | -3.4899649157959889e-01,1.1281501080206573e-08,9.2821139149853654e-02,8.8177577655787553e-01,9.2821115231686013e-02,8.8177553500332861e-01 32 | 8.6935674651502350e-09,-1.6586892181049041e-08,3.0576187545095601e-01,-3.0576191450739582e-01,1.2127668809933916e-08,-9.9919508441805847e-08 33 | 4.9562377919645856e-01,-4.9562384420327860e-01,1.1576549204246370e-08,-1.3643117483633088e-01,-1.2302268480058822e+00,1.3643118508207647e-01 34 | 1.2302270317409092e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo_basis.gamma=0.win=5_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,2,13 2 | 8.0578295072309514e-02,-1.4162784997591951e-01,-2.3748224735853374e-01,-2.3748217891643625e-01,1.4503878416605176e-08,-9.8068045647795987e-01 3 | -3.4899658653980259e-01,-3.4899649157959117e-01,1.1281501197561282e-08,9.2821139149852974e-02,8.8177577655788364e-01,9.2821115231684168e-02 4 | 8.8177553500331440e-01,8.6935683007728097e-09,-1.6586895679683905e-08,3.0576187545095368e-01,-3.0576191450739826e-01,1.2127668586629059e-08 5 | -9.9919513311105213e-08,4.9562377919645634e-01,-4.9562384420327971e-01,1.1576549086785098e-08,-1.3643117483633058e-01,-1.2302268480058749e+00 6 | 1.3643118508207699e-01,1.2302270317409145e+00 7 | Dimension,2,13 8 | 8.0578295072309111e-02,-1.4162784997591291e-01,-2.3748224735853113e-01,-2.3748217891643830e-01,1.4503878302388163e-08,-9.8068045647796986e-01 9 | -3.4899658653980126e-01,-3.4899649157959889e-01,1.1281501080206573e-08,9.2821139149853654e-02,8.8177577655787553e-01,9.2821115231686013e-02 10 | 8.8177553500332861e-01,8.6935674651502350e-09,-1.6586892181049041e-08,3.0576187545095601e-01,-3.0576191450739582e-01,1.2127668809933916e-08 11 | -9.9919508441805847e-08,4.9562377919645856e-01,-4.9562384420327860e-01,1.1576549204246370e-08,-1.3643117483633088e-01,-1.2302268480058822e+00 12 | 1.3643118508207647e-01,1.2302270317409092e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/lo_basis.gamma=default.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,13 2 | 9.9506069514886897e-01,2.7752992978578334e-02,1.6017309470001567e-03,1.6017307802393154e-03,-2.0283313890168198e-10,-1.2819729509628746e-02 3 | -2.1780049140020250e-03,-2.1780048289320592e-03,7.5562395788579339e-11,3.8695521681722788e-04,2.7974927276545147e-03,3.8695522433982522e-04 4 | 2.7974926687892279e-03,-2.0786668994193805e-01,4.6166177720994850e-01,1.1256728501554372e-01,1.1256726767252316e-01,-4.7757910652874364e-09 5 | 4.5400098553642732e-01,5.4699248244083613e-02,5.4699239096071120e-02,-1.4935821067139812e-09,1.4692140639053922e-01,1.6028888823126088e-03 6 | 1.4692139099989870e-01,1.6028856419927303e-03,8.4984678322252589e-09,-1.9182198428644086e-08,3.6833417743180247e-01,-3.6833416492144222e-01 7 | -3.3283041534110201e-09,-2.7386200114322805e-08,1.8324507999690512e-01,-1.8324507449878205e-01,2.3793042119106210e-10,2.5465392328028974e-01 8 | 1.7591661066678344e-01,-2.5465391102985296e-01,-1.7591659963552667e-01,-9.9127148059990122e-02,2.1930704542540574e-01,-3.6664731118114940e-01 9 | -3.6664733821644929e-01,-2.4409379045697059e-08,4.0552771920388986e-01,-2.3687273601639566e-01,-2.3687275648611478e-01,-1.3307044183361742e-08 10 | -1.6524803696593174e-01,-1.2202524950678661e-01,-1.6524804125961159e-01,-1.2202524972737973e-01,5.9366499233446256e-09,-1.2423087142195945e-08 11 | 1.1170620435423701e-08,-4.6498800225852882e-09,-6.4954748892538861e-01,-3.6374590282731261e-08,9.7618677799409537e-09,-2.4078531611250373e-09 12 | -5.0140755257294956e-01,9.4473659799671160e-10,1.3611340614391498e-09,1.1265198020470671e-08,4.3511308073462371e-08,8.0578295072309514e-02 13 | -1.4162784997591951e-01,-2.3748224735853374e-01,-2.3748217891643625e-01,1.4503878416605176e-08,-9.8068045647795987e-01,-3.4899658653980259e-01 14 | -3.4899649157959117e-01,1.1281501197561282e-08,9.2821139149852974e-02,8.8177577655788364e-01,9.2821115231684168e-02,8.8177553500331440e-01 15 | 8.6935683007728097e-09,-1.6586895679683905e-08,3.0576187545095368e-01,-3.0576191450739826e-01,1.2127668586629059e-08,-9.9919513311105213e-08 16 | 4.9562377919645634e-01,-4.9562384420327971e-01,1.1576549086785098e-08,-1.3643117483633058e-01,-1.2302268480058749e+00,1.3643118508207699e-01 17 | 1.2302270317409145e+00 18 | Dimension,7,13 19 | 9.9506069514886897e-01,2.7752992978578327e-02,1.6017309470001586e-03,1.6017307802393104e-03,-2.0283313844237175e-10,-1.2819729509628727e-02 20 | -2.1780049140020328e-03,-2.1780048289320388e-03,7.5562395598430950e-11,3.8695521681722392e-04,2.7974927276545342e-03,3.8695522433983417e-04 21 | 2.7974926687891802e-03,-2.0786668994193827e-01,4.6166177720994866e-01,1.1256728501554367e-01,1.1256726767252304e-01,-4.7757910196214591e-09 22 | 4.5400098553642904e-01,5.4699248244083634e-02,5.4699239096071599e-02,-1.4935820894195499e-09,1.4692140639053905e-01,1.6028888823122528e-03 23 | 1.4692139099989865e-01,1.6028856419913885e-03,8.4984679242321928e-09,-1.9182198922022779e-08,3.6833417743180291e-01,-3.6833416492144216e-01 24 | -3.3283039837189078e-09,-2.7386199752773587e-08,1.8324507999690579e-01,-1.8324507449878166e-01,2.3793059619450106e-10,2.5465392328029013e-01 25 | 1.7591661066678327e-01,-2.5465391102985296e-01,-1.7591659963552722e-01,-9.9127148059990206e-02,2.1930704542540597e-01,-3.6664731118114952e-01 26 | -3.6664733821644974e-01,-2.4409379409262470e-08,4.0552771920389108e-01,-2.3687273601639522e-01,-2.3687275648611422e-01,-1.3307044352858269e-08 27 | -1.6524803696593224e-01,-1.2202524950678682e-01,-1.6524804125961209e-01,-1.2202524972738175e-01,5.9366499248054274e-09,-1.2423087108472835e-08 28 | 1.1170620718300573e-08,-4.6498792558713634e-09,-6.4954748892538838e-01,-3.6374590429263097e-08,9.7618679448025315e-09,-2.4078537050400252e-09 29 | -5.0140755257294944e-01,9.4473731023400340e-10,1.3611329271141683e-09,1.1265196960665544e-08,4.3511309585332292e-08,8.0578295072309111e-02 30 | -1.4162784997591291e-01,-2.3748224735853113e-01,-2.3748217891643830e-01,1.4503878302388163e-08,-9.8068045647796986e-01,-3.4899658653980126e-01 31 | -3.4899649157959889e-01,1.1281501080206573e-08,9.2821139149853654e-02,8.8177577655787553e-01,9.2821115231686013e-02,8.8177553500332861e-01 32 | 8.6935674651502350e-09,-1.6586892181049041e-08,3.0576187545095601e-01,-3.0576191450739582e-01,1.2127668809933916e-08,-9.9919508441805847e-08 33 | 4.9562377919645856e-01,-4.9562384420327860e-01,1.1576549204246370e-08,-1.3643117483633088e-01,-1.2302268480058822e+00,1.3643118508207647e-01 34 | 1.2302270317409092e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/losc_eig.txt: -------------------------------------------------------------------------------- 1 | Dimension,1,13 2 | -2.0222572497385869e+01,-1.2107155159953009e+00,-6.4086844376617658e-01,-5.6314187784152181e-01,-4.7852036721875274e-01,1.2598985625891368e-01 3 | 2.1000929542677069e-01,8.3872773953414759e-01,9.6370307134296584e-01,1.0081305100847724e+00,1.0944581599345320e+00,1.1594773708067188e+00 4 | 1.5842774043443679e+00 5 | Dimension,1,13 6 | -2.0222572499188313e+01,-1.2107155167455537e+00,-6.4086844376616880e-01,-5.6314187784153436e-01,-4.7852036721875607e-01,1.2598985613657071e-01 7 | 2.1000929542677091e-01,8.3872773953415192e-01,9.6370307134301847e-01,1.0081305100847722e+00,1.0944581600406711e+00,1.1594773708067307e+00 8 | 1.5842774043443546e+00 -------------------------------------------------------------------------------- /tests/losc/data/H2O/mol.inp: -------------------------------------------------------------------------------- 1 | 2 | $qm 3 | xyz mol.xyz 4 | spin 2 5 | charge 0 6 | mult 1 7 | method dft 8 | xcfunc b3lyp 9 | guess atom 10 | iter 300 11 | dentol 1.0E-004 12 | etol 1.0E-008 13 | print 1 14 | diis 12 0.30 15 | directvee 16 | basis H H.6-31G 17 | basis O O.6-31G 18 | fitbasis H H.6-31GSS 19 | fitbasis O O.6-31GSS 20 | dolosc 21 | end 22 | 23 | $setlosc 24 | print 1 25 | losc_2_2 26 | post 27 | write dipole_ao dipole_ao.bin 28 | write ao_overlap ao_overlap.bin 29 | write dfa_h dfa_h.bin 30 | write dfa_density dfa_density.bin 31 | write df_pmn_matrix df_pmn.bin 32 | write df_Vpq_inverse df_Vpq_inv.bin 33 | write grid_weight grid_wt.bin 34 | write grid_basis_value grid_basis.bin 35 | write lo_coef lo.bin 36 | write umatrix u.bin 37 | write lo_basis_coef lo_basis.bin 38 | write localocc localocc.bin 39 | write losc_eig_proj losc_eig.bin 40 | write kappa kappa.bin 41 | write losc_hamiltonian_correction losc_H_corr.bin 42 | 43 | end 44 | 45 | $doqm 46 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/mol.xyz: -------------------------------------------------------------------------------- 1 | 3 2 | H20 3 | O 0 0 0 4 | H 1 0 0 5 | H 0 1 0 6 | -------------------------------------------------------------------------------- /tests/losc/data/H2O/u.gamma=0.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,7 2 | 9.9616604987073243e-01,-7.9361357274609787e-02,-1.2040465299902662e-08,-3.4892826217705807e-02,-1.0004459520942381e-07,1.1724620889537391e-02 3 | -7.2162416177481700e-09,-2.8783031715361664e-03,1.7453840422709729e-01,3.3593330385865555e-01,-2.6711779854387580e-01,-9.3304801207832961e-08 4 | 6.3101206059695525e-01,-6.2221277491029481e-01,2.8783038625719865e-03,-1.7453837755707877e-01,3.3593323578084638e-01,2.6711782617394514e-01 5 | 5.3244384963116713e-09,-6.3101193250974297e-01,-6.2221293718055481e-01,4.4133133400277143e-02,3.1142360153073317e-01,-2.8721231223931180e-06 6 | 6.0947693173991957e-01,-7.0710666069208483e-01,1.7206291586885991e-01,-1.4627283778099821e-06,4.4133210185524567e-02,3.1142282393411574e-01 7 | 1.1924154394263356e-06,6.0947694975587230e-01,7.0710690167336332e-01,1.7206324945198120e-01,6.3173530433781472e-07,-4.3250151343225102e-02 8 | -6.0778518197508935e-01,6.2221243751884103e-01,2.3786056644069045e-01,-2.6840251377070752e-06,2.6860678917613273e-01,3.3593306373585247e-01 9 | 4.3250231519034420e-02,6.0778517001911769e-01,6.2221327456396303e-01,-2.3785858749560787e-01,-1.8875733912286287e-06,-2.6860610130024787e-01 10 | 3.3593347589974371e-01 11 | Dimension,7,7 12 | 9.9616604866272340e-01,-7.9361364211650520e-02,-4.1451235275257581e-09,-3.4892850564101241e-02,-1.3482085387555946e-08,1.1724604115821564e-02 13 | -3.8948754949141730e-09,-2.8782993779444543e-03,1.7453839439352781e-01,3.3593329385656323e-01,-2.6711780454032114e-01,-6.6557379227579209e-09 14 | 6.3101205496571711e-01,-6.2221278622301124e-01,2.8782985972949648e-03,-1.7453837265685210e-01,3.3593324125510615e-01,2.6711783137164569e-01 15 | -4.5537900429268504e-08,-6.3101193751902074e-01,-6.2221292831242259e-01,4.4133187072733317e-02,3.1142341225862558e-01,-1.1981316750951163e-06 16 | 6.0947656299369335e-01,-7.0710706283377767e-01,1.7206289822679760e-01,-5.8242283060986080e-07,4.4133199371823896e-02,3.1142305887585220e-01 17 | 2.9763238497411242e-07,6.0947729357914504e-01,7.0710649953804883e-01,1.7206326172656977e-01,1.6582667022918407e-07,-4.3250162983194229e-02 18 | -6.0778516198630461e-01,6.2221264446138269e-01,2.3786012714473725e-01,-1.1792487651065867e-06,2.6860660609214959e-01,3.3593317255153149e-01 19 | 4.3250204571871724e-02,6.0778516993274478e-01,6.2221307007275861e-01,-2.3785907451241739e-01,-4.9241667739369443e-07,-2.6860629001612363e-01 20 | 3.3593336255956302e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2O/u.gamma=0.win=5_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,2,2 2 | 7.0710685256667816e-01,-7.0710670980640966e-01,7.0710670980640966e-01,7.0710685256667816e-01 3 | Dimension,2,2 4 | 7.0710685256667816e-01,-7.0710670980640966e-01,7.0710670980640966e-01,7.0710685256667816e-01 -------------------------------------------------------------------------------- /tests/losc/data/H2O/u.gamma=default.win=0_7.txt: -------------------------------------------------------------------------------- 1 | Dimension,7,7 2 | 9.9999999999999889e-01,-1.0069504119414307e-08,0.0000000000000000e+00,-8.7637721524202917e-09,0.0000000000000000e+00,4.7786902703599761e-08 3 | 0.0000000000000000e+00,1.0068073781340531e-08,9.9999990351019297e-01,-1.1598883551810035e-16,-4.3642524176101095e-04,0.0000000000000000e+00 4 | -5.0125971250642316e-05,1.8140505715474690e-13,0.0000000000000000e+00,0.0000000000000000e+00,9.9999979558937424e-01,0.0000000000000000e+00 5 | 0.0000000000000000e+00,0.0000000000000000e+00,6.3939128064002153e-04,8.6413212934123908e-09,4.3655672794772722e-04,6.7549740224376214e-19 6 | 9.9999638347575759e-01,0.0000000000000000e+00,2.6537621651369719e-03,-1.0564693085722914e-15,0.0000000000000000e+00,0.0000000000000000e+00 7 | 0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,-4.7809498451575699e-08 8 | 4.8967621174837147e-05,7.4745419327829706e-11,-2.6537837919055336e-03,0.0000000000000000e+00,9.9999647751066700e-01,-1.1690088106026827e-07 9 | -5.5889754517549477e-15,5.5429546133605475e-12,-6.3939128064001709e-04,-3.1022859119600530e-10,0.0000000000000000e+00,1.1690049318576220e-07 10 | 9.9999979558936736e-01 11 | Dimension,7,7 12 | 9.9999999999999889e-01,-1.0069504119414307e-08,0.0000000000000000e+00,-8.7637721524202917e-09,0.0000000000000000e+00,4.7786902703599761e-08 13 | 0.0000000000000000e+00,1.0068073708061307e-08,9.9999990350649093e-01,-1.1598883552382864e-16,-4.3643372182519105e-04,0.0000000000000000e+00 14 | -5.0125993754797180e-05,1.8140505716370586e-13,0.0000000000000000e+00,0.0000000000000000e+00,9.9999979558937424e-01,0.0000000000000000e+00 15 | 0.0000000000000000e+00,0.0000000000000000e+00,6.3939128064002153e-04,8.6413213787906119e-09,4.3656520804175752e-04,6.7549641864743558e-19 16 | 9.9999638347205666e-01,0.0000000000000000e+00,2.6537621647118987e-03,-1.0564677702402008e-15,0.0000000000000000e+00,0.0000000000000000e+00 17 | 0.0000000000000000e+00,0.0000000000000000e+00,1.0000000000000000e+00,0.0000000000000000e+00,0.0000000000000000e+00,-4.7809498451575699e-08 18 | 4.8967621174837147e-05,7.4745419327829706e-11,-2.6537837919055336e-03,0.0000000000000000e+00,9.9999647751066700e-01,-1.1690088106026827e-07 19 | -5.5889754517549477e-15,5.5429546133605475e-12,-6.3939128064001709e-04,-3.1022859119600530e-10,0.0000000000000000e+00,1.1690049318576220e-07 20 | 9.9999979558936736e-01 -------------------------------------------------------------------------------- /tests/losc/local_occ_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "matrix_helper.hpp" 10 | #include "matrix_io.hpp" 11 | #include 12 | 13 | using std::move; 14 | using std::string; 15 | using std::vector; 16 | using namespace losc; 17 | 18 | struct LocalOccupationTest : public ::testing::TestWithParam { 19 | string file_path; 20 | string dir_path; 21 | 22 | virtual void SetUp() override 23 | { 24 | file_path = __FILE__; 25 | dir_path = file_path.substr(0, file_path.rfind("/")); 26 | } 27 | 28 | virtual void TearDown() override {} 29 | }; 30 | 31 | TEST_P(LocalOccupationTest, test) 32 | { 33 | // load data. 34 | string mol = GetParam(); 35 | const char *mol_str = mol.c_str(); 36 | string S_path = dir_path + "/data/" + mol + "/ao_overlap.txt"; 37 | string C_lo_path = dir_path + "/data/" + mol + "/lo.txt"; 38 | string D_path = dir_path + "/data/" + mol + "/dfa_density.txt"; 39 | string L_ref_path = dir_path + "/data/" + mol + "/localocc.txt"; 40 | LOSCMatrix S = move(test::read_matrices_from_txt(S_path)[0]); 41 | LOSCMatrix C_lo = test::read_matrices_from_txt(C_lo_path)[0].transpose(); 42 | LOSCMatrix D = move(test::read_matrices_from_txt(D_path)[0]); 43 | LOSCMatrix L_ref = move(test::read_matrices_from_txt(L_ref_path)[0]); 44 | 45 | // Do calculation. 46 | LOSCMatrix L_calc = losc::local_occupation(C_lo, S, D); 47 | 48 | // Testing. 49 | // True condition is the calculated Losc local occupation matrix matches 50 | // the reference to the 8-th digit. 51 | bool status = test::mtx_is_cwise_equal(L_calc, L_ref, 1e-8); 52 | EXPECT_TRUE(status); 53 | if (!status) { 54 | std::ofstream log; 55 | string log_file = "LocalOccTest.test." + mol + ".log"; 56 | log.open(log_file); 57 | log << "data dir path: " << dir_path << std::endl; 58 | log << "LocalOcc matrix: reference\n"; 59 | test::mtx_show_full(L_ref, log); 60 | log << "LocalOcc matrix: calculated\n"; 61 | test::mtx_show_full(L_calc, log); 62 | log.close(); 63 | std::cout << "Test Failure: See log file for more information: " 64 | << log_file << std::endl; 65 | } 66 | } 67 | 68 | INSTANTIATE_TEST_SUITE_P(correction_test, LocalOccupationTest, 69 | ::testing::Values("H2.1A", "H2.10A", "H2O")); 70 | -------------------------------------------------------------------------------- /tests/losc/matrix_checker_test.cpp: -------------------------------------------------------------------------------- 1 | #include "matrix_helper.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::vector; 8 | using namespace losc; 9 | using namespace test; 10 | 11 | /** 12 | * Test is_symmetric() method. 13 | */ 14 | TEST(MatrixCheckerTest, is_symmetric_test) 15 | { 16 | LOSCMatrix A = LOSCMatrix::Zero(10, 10); 17 | // zero matrix should be regarded as symmetric. 18 | EXPECT_TRUE(mtx_is_symmetric(A)); 19 | EXPECT_TRUE(mtx_is_symmetric(A, 1e-16)); 20 | EXPECT_TRUE(mtx_is_symmetric(A, 1e-300)); 21 | 22 | mtx_randomize(A, 0, 1); 23 | EXPECT_FALSE( 24 | mtx_is_symmetric(A)); // random matrix usually is not symmetric. 25 | EXPECT_TRUE(mtx_is_symmetric(A, 2)); // lower threshold to be symmetric. 26 | mtx_to_symmetric(A, "L"); 27 | EXPECT_TRUE(mtx_is_symmetric(A)); // real symmetric matrix. 28 | EXPECT_TRUE(mtx_is_symmetric( 29 | A, -1e-16)); // happended to set it to negative threshold. 30 | 31 | // if customized threshold working? 32 | double thred = 1e-8; 33 | A(2, 3) = A(3, 2) - thred; 34 | EXPECT_FALSE(mtx_is_symmetric(A, thred / 10)); 35 | EXPECT_TRUE(mtx_is_symmetric(A, thred * 10)); 36 | 37 | // non-square matrix. 38 | LOSCMatrix B(2, 3); 39 | EXPECT_FALSE(mtx_is_symmetric(B)); 40 | EXPECT_FALSE(mtx_is_symmetric(B, 100)); 41 | EXPECT_FALSE(mtx_is_symmetric(B, 1e-300)); 42 | } 43 | 44 | /** 45 | * Test is_cwise_equal() method. 46 | */ 47 | TEST(MatrixCheckerTest, is_cwise_equal_test) 48 | { 49 | LOSCMatrix A = LOSCMatrix::Zero(10, 8); 50 | LOSCMatrix B = LOSCMatrix::Zero(10, 8); 51 | // real zero matrix should be equal. 52 | EXPECT_TRUE(mtx_is_cwise_equal(A, B)); 53 | EXPECT_TRUE(mtx_is_cwise_equal(A, B, 1e-16)); 54 | EXPECT_TRUE(mtx_is_cwise_equal(A, B, 1e-300)); 55 | 56 | // customized threshold 57 | double thred = 1e-8; 58 | A(1, 1) += thred; 59 | EXPECT_FALSE(mtx_is_cwise_equal(A, B, thred / 10)); 60 | EXPECT_TRUE(mtx_is_cwise_equal(A, B, thred * 10)); 61 | 62 | // random matrix usually is not equal to each other. 63 | mtx_randomize(A, 0, 1); 64 | mtx_randomize(B, 0, 1); 65 | EXPECT_FALSE(mtx_is_cwise_equal(A, B)); 66 | } 67 | -------------------------------------------------------------------------------- /tests/losc/matrix_helper.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Definition matrix class. 4 | */ 5 | 6 | #include "matrix_helper.hpp" 7 | 8 | #include 9 | #include // std::setprecision 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace losc; 17 | 18 | namespace test { 19 | 20 | static std::mt19937 g_rand_generator_mt19937_seed_fixed(1); 21 | 22 | /** 23 | * @details The matrix elements are printed in the format `%16.8e`. 24 | */ 25 | void mtx_show_full(const LOSCMatrix &m, std::ostream &os, 26 | size_t elements_per_line) 27 | { 28 | size_t row = m.rows(); 29 | size_t col = m.cols(); 30 | std::ios_base::fmtflags os_flags(os.flags()); 31 | os << std::fixed; 32 | os << "dimension: " << row << " x " << col << ", showing the full matrix." 33 | << std::endl; 34 | for (size_t i = 0; i < row; ++i) { 35 | os << std::setw(5) << i + 1 << ":\n"; 36 | os << std::scientific; 37 | for (int j = 1; j <= col; ++j) { 38 | os << std::setprecision(8) << std::setw(16) << m(i, j - 1); 39 | if (j != col) 40 | os << ","; 41 | if (j % elements_per_line == 0) 42 | os << std::endl; 43 | } 44 | os << std::endl; 45 | } 46 | os << std::endl; 47 | os.flush(); 48 | os.flags(os_flags); 49 | } 50 | 51 | /** 52 | * @details The matrix elements are printed in the format `%16.8e`. 53 | */ 54 | void mtx_show_lower(const LOSCMatrix &m, std::ostream &os, 55 | size_t elements_per_line) 56 | { 57 | std::ios_base::fmtflags os_flags(os.flags()); 58 | os << std::fixed; 59 | os << "dimension: " << m.rows() << " x " << m.cols() 60 | << ", showing the lower triangular parts." << std::endl; 61 | for (size_t i = 0; i < m.rows(); i++) { 62 | os << std::setw(5) << i + 1 << ":\n"; 63 | os << std::scientific; 64 | for (int j = 0; j <= i; j++) { 65 | os << std::setprecision(8) << std::setw(15) << m(i, j); 66 | if (j != i) 67 | os << ","; 68 | if ((j + 1) % elements_per_line == 0) 69 | os << std::endl; 70 | } 71 | os << std::endl; 72 | } 73 | os << std::endl; 74 | os.flush(); 75 | os.flags(os_flags); 76 | } 77 | 78 | bool mtx_is_symmetric(const LOSCMatrix &m, double threshold) 79 | { 80 | threshold = std::abs(threshold); 81 | if (!mtx_is_square(m)) { 82 | return false; 83 | } 84 | for (size_t i = 0; i < m.rows(); i++) { 85 | for (size_t j = 0; j < i; j++) { 86 | if (std::abs(m(i, j) - m(j, i)) > threshold) { 87 | return false; 88 | } 89 | } 90 | } 91 | return true; 92 | } 93 | 94 | /** 95 | * @note The dimension of two matrices will be compared as well. If not matched, 96 | * it will return false. 97 | */ 98 | bool mtx_is_cwise_equal(const LOSCMatrix &m, const LOSCMatrix &other, 99 | double threshold) 100 | { 101 | if (!mtx_is_same_dimension_to(m, other)) { 102 | return false; 103 | } 104 | LOSCMatrix diff = m - other; 105 | return diff.isZero(threshold); 106 | } 107 | 108 | bool mtx_is_same_dimension_to(const LOSCMatrix &m, const LOSCMatrix &other) 109 | { 110 | return ((m.rows() == other.rows()) && (m.cols() == other.cols())); 111 | } 112 | 113 | void mtx_to_symmetric(LOSCMatrix &m, const string &uplo) 114 | { 115 | const size_t row = m.rows(); 116 | const size_t col = m.cols(); 117 | if (!mtx_is_square(m)) { 118 | throw losc::exception::DimensionError( 119 | "Cannot symmetrize a matrix that is not squared."); 120 | } 121 | if (uplo == "U") { 122 | for (size_t i = 0; i < row; i++) { 123 | for (size_t j = 0; j < i; j++) { 124 | m(i, j) = m(j, i); 125 | } 126 | } 127 | } else if (uplo == "L") { 128 | for (size_t i = 0; i < row; i++) { 129 | for (size_t j = 0; j < i; j++) { 130 | m(j, i) = m(i, j); 131 | } 132 | } 133 | } 134 | } 135 | 136 | /** 137 | * @details This function is implemented with `std::random_device` to generate 138 | * random seed to `std::mt1993` radom number generator, and use 139 | * `std::uniform_real_distribution` to keep uniform distributed. 140 | * 141 | * @see Eigen::setRandom() can also set a matrix element normally distributed in 142 | * range [-1 : 1]. 143 | */ 144 | void mtx_randomize(LOSCMatrix &m, double a, double b) 145 | { 146 | std::random_device 147 | rd; // Will be used to obtain a seed for the random number engine 148 | std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() 149 | std::uniform_real_distribution<> dis(a, b); 150 | for (size_t i = 0; i < m.rows(); i++) { 151 | for (size_t j = 0; j < m.cols(); j++) { 152 | m(i, j) = dis(gen); 153 | } 154 | } 155 | } 156 | 157 | /** 158 | * @details `std::mt1993` seeded with constant value 1 is used as the radom 159 | * number generator, and use `std::uniform_real_distribution` to keep uniform 160 | * distributed. 161 | * 162 | * @see Eigen::setRandom() can also set a matrix element normally distributed in 163 | * range [-1 : 1]. 164 | */ 165 | void mtx_randomize_seed_fixed(LOSCMatrix &m, double a, double b) 166 | { 167 | std::uniform_real_distribution<> dis(a, b); 168 | for (size_t i = 0; i < m.rows(); i++) { 169 | for (size_t j = 0; j < m.cols(); j++) { 170 | m(i, j) = dis(g_rand_generator_mt19937_seed_fixed); 171 | } 172 | } 173 | } 174 | 175 | } // namespace test 176 | -------------------------------------------------------------------------------- /tests/losc/matrix_helper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_TESTS_MATRIX_HELPER_HPP_ 2 | #define _LOSC_TESTS_MATRIX_HELPER_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace test { 11 | 12 | using losc::LOSCMatrix; 13 | using std::string; 14 | 15 | /** 16 | * @brief Print out the full matrix to a `std::ostream`. 17 | * @param [in] os: The output stream object to print the matrix. Default 18 | * `os = std::cout`. 19 | * @param [in] elements_per_line: number of elements being printed per line. 20 | * Default `element_per_line = 5`. 21 | * 22 | * @note This function will not change the settings of the `os`. 23 | * @note The format of printing matrix in this matrix is fixed. If you want 24 | * print the matrix in a more flexible way, use the Eige::LOSCMatrix 25 | * interface. Eigen library provides the overloaded `operator <<` to insert 26 | * an Eigen matrix into an `std::ostream`. It also provide `Eigen::IOFormat` 27 | * class to configure the output matrix format. 28 | */ 29 | void mtx_show_full(const LOSCMatrix &m, std::ostream &os = std::cout, 30 | size_t elements_per_line = 5); 31 | 32 | /** 33 | * @brief Print out the lower triangular matrix (including diagonal 34 | * elements). 35 | * @param [in] os: The output stream object to print the matrix. Default 36 | * `os = std::cout`. 37 | * @param [in] elements_per_line: number of elements being printed per line. 38 | * Default `elements_per_line = 5`. 39 | * 40 | * @note This function will not change the settings of the `os`. 41 | * @see losc::show_full() for more format information. 42 | */ 43 | void mtx_show_lower(const LOSCMatrix &m, std::ostream &os = std::cout, 44 | size_t elements_per_line = 5); 45 | 46 | /** 47 | * @brief Check if the matrix is square or not. 48 | * @return bool 49 | */ 50 | inline bool mtx_is_square(const LOSCMatrix &m) 51 | { 52 | return (m.rows() == m.cols()); 53 | } 54 | 55 | /** 56 | * @brief Check if or not the matrix is numerically symmetric based on 57 | * the input threshold. Default `threshold = 1e-10`. 58 | * 59 | * @param [in] threshold: the threshold of testing numerical equality 60 | * between two float-point numbers. 61 | * @return bool. 62 | */ 63 | bool mtx_is_symmetric(const LOSCMatrix &m, double threshold = 1e-10); 64 | 65 | /** 66 | * @brief Check if or not the matrix is numerically equal to the other 67 | * matrix by element-wise (coefficient-wise) comparision. 68 | * Default `threshold = 1e-10`. 69 | * 70 | * @param [in] other: The other matrix to be compared with. 71 | * @return bool 72 | * 73 | * @see Einen library also provides a similar function `Eigen::isApprox`. 74 | */ 75 | bool mtx_is_cwise_equal(const LOSCMatrix &m, const LOSCMatrix &other, 76 | double threshold = 1e-10); 77 | 78 | /** 79 | * @brief Check if or not the matrix has the same dimension to the other 80 | * matrix. 81 | * 82 | * @param [in] other: The other matrix to be compared with. 83 | * @return bool. 84 | */ 85 | bool mtx_is_same_dimension_to(const LOSCMatrix &m, const LOSCMatrix &other); 86 | 87 | /** 88 | * @brief Make the matrix to be symmetric. 89 | * 90 | * @param [in] uplo: when \p uplo equals to "U", the upper triangular part 91 | * is used. when \p uplo equals to "L", the lower triangular part is used. 92 | */ 93 | void mtx_to_symmetric(LOSCMatrix &m, const string &uplo); 94 | 95 | /** 96 | * @brief Make the matrix to be random with elements uniformly distributed 97 | * in range [a, b). 98 | * 99 | * @param [in] a: left range bound. 100 | * @param [in] b: right range bound. 101 | * 102 | * @note The random number generator is initialized with a NON-FIXED seed. 103 | * So the randomness behavior is not repeatable at running time. 104 | */ 105 | void mtx_randomize(LOSCMatrix &m, double a, double b); 106 | 107 | /** 108 | * @brief Make the matrix to be random with elements uniformly distributed 109 | * in range [a, b). 110 | * 111 | * @param [in] a: left range bound. 112 | * @param [in] b: right range bound. 113 | * @return Matrix&: the randomized matrix itself. 114 | * 115 | * @note The random number generator is initialized with a FIXED seed. So 116 | * the randomness behavior is repeatable at running time. 117 | */ 118 | void mtx_randomize_seed_fixed(LOSCMatrix &m, double a, double b); 119 | 120 | } // namespace test 121 | 122 | #endif // _LOSC_SRC_MATRIX_H_ 123 | -------------------------------------------------------------------------------- /tests/losc/matrix_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "matrix_io.hpp" 10 | #include 11 | #include 12 | 13 | using namespace losc; 14 | namespace test { 15 | /** 16 | * @note The txt file `fname` will always be overwritten if `Mat` is not empty. 17 | */ 18 | void write_matrices_to_txt(vector &Mat, const string &fname, 19 | size_t num_per_line) 20 | { 21 | if (Mat.size() == 0) 22 | return; 23 | 24 | FILE *f = fopen(fname.c_str(), "w"); 25 | if (f == NULL) 26 | throw losc::exception::LoscException( 27 | "Cannot open file to write matrices:" + fname); 28 | for (size_t i = 0; i < Mat.size(); ++i) { 29 | const LOSCMatrix &A = Mat[i]; 30 | if (i == 0) 31 | fprintf(f, "Dimension,%zu,%zu\n", A.rows(), A.cols()); 32 | else 33 | fprintf(f, "\nDimension,%zu,%zu\n", A.rows(), A.cols()); 34 | 35 | // loop over each elements. 36 | size_t n = 0; 37 | const size_t size = A.size(); 38 | for (size_t ii = 0; ii < A.rows(); ++ii) { 39 | for (size_t jj = 0; jj < A.cols(); ++jj) { 40 | const auto val = A(ii, jj); 41 | if (n != num_per_line && ii != size - 1) { 42 | fprintf(f, "%.16e,", val); 43 | ++n; 44 | } else if (n == num_per_line && ii != size - 1) { 45 | fprintf(f, "%.16e\n", val); 46 | n = 0; 47 | } else { 48 | fprintf(f, "%.16e", val); 49 | } 50 | } 51 | } 52 | } 53 | fclose(f); 54 | } 55 | 56 | /** 57 | * @brief split string with given delimeter. 58 | * @param [in] str: input string to be splitted. 59 | * @param [in] delim: delimeter. 60 | * @param [in, out] str_split: On exit, it stores the splitted string. 61 | */ 62 | static void str_split(std::string &str, const char delim, 63 | std::vector &str_split) 64 | { 65 | str_split.clear(); 66 | std::stringstream str_stream(str + std::string(1, delim)); 67 | std::string word; 68 | while (std::getline(str_stream, word, delim)) { 69 | str_split.push_back(word); 70 | } 71 | } 72 | 73 | std::vector read_matrices_from_txt(const string &fname) 74 | { 75 | std::ifstream fin; 76 | fin.open(fname); 77 | if (!fin) 78 | throw losc::exception::LoscException( 79 | "Cannot open file to write matrices:" + fname); 80 | 81 | bool is_first_line = true; 82 | std::string line; 83 | std::vector line_split; 84 | std::vector rst; 85 | std::size_t n_row = 0; 86 | std::size_t n_col = 0; 87 | std::size_t count = 0; 88 | 89 | // loop over each line in the txt file 90 | std::size_t line_num = 0; 91 | while (std::getline(fin, line)) { 92 | str_split(line, ',', line_split); 93 | auto p_data = line_split.begin(); 94 | if (line_split[0] == "Dimension") { 95 | // now it starts to read a new matrix. 96 | // Before that, check if the last matrix is read successfully or 97 | // not. 98 | if (!is_first_line) { 99 | if (count != rst.back().size()) { 100 | throw losc::exception::LoscException( 101 | "Error in read matrix, unmatched element size: file " 102 | "name = " + 103 | fname); 104 | } 105 | } 106 | // read dimension information for the new matrix. 107 | if (line_split.size() < 3) { 108 | throw losc::exception::LoscException( 109 | "Cannot read matrix dimension: file name = " + fname); 110 | } 111 | try { 112 | n_row = std::stoi(line_split[1]); 113 | n_col = std::stoi(line_split[2]); 114 | } catch (...) { 115 | throw losc::exception::LoscException( 116 | "Failed to read matrix dimension. file name = " + fname); 117 | } 118 | // create a new matrix and push it back to matrix vector. 119 | LOSCMatrix t(n_row, n_col); 120 | t.setZero(); 121 | rst.push_back(std::move(t)); 122 | p_data += 3; 123 | count = 0; // set matrix element count as zero. 124 | } 125 | // put matrix element in current line into the matrix object. 126 | for (; p_data != line_split.end(); ++p_data) { 127 | try { 128 | const size_t i = count / n_col; 129 | const size_t j = count % n_col; 130 | // current_matrix->data()[count] = std::stod(*p_data); 131 | rst.back()(i, j) = std::stod(*p_data); 132 | ++count; 133 | } catch (...) { 134 | std::stringstream msg; 135 | msg << "Failed to read matrix element at line:" << line_num + 1 136 | << ", column:" << p_data - line_split.begin() + 1 137 | << std::endl; 138 | msg << "Failed element value: " << *p_data << std::endl; 139 | msg << "File name: " << fname << std::endl; 140 | throw losc::exception::LoscException(msg.str()); 141 | } 142 | } 143 | // at this point, the first line has been parsed. 144 | is_first_line = false; 145 | line_num++; 146 | } 147 | fin.close(); 148 | return rst; 149 | } 150 | 151 | } // namespace test 152 | -------------------------------------------------------------------------------- /tests/losc/matrix_io.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOSC_TESTS_MATRIX_IO_H_ 2 | #define _LOSC_TESTS_MATRIX_IO_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace test { 10 | 11 | using losc::LOSCMatrix; 12 | using std::string; 13 | using std::vector; 14 | 15 | /** 16 | * @brief Write a vector of matrices into a txt file. 17 | * @details The matrices are write in order. For each matrix, the format is the 18 | * following. The first line constaints the number of row and columns of the 19 | * matrix. This line is garranted to be the format 20 | * `printf("Dimension,%zu,%zu\n", row, col) and it is used to indicate the 21 | * separation of different matrices. The following multiples lines contains all 22 | * the matrix elements. Each matrix elements are comma-separated. The matrix 23 | * elements are written in column-wise order. 24 | * 25 | * @param [in] Mat: The set of input matrices to be written. 26 | * @param [in] fname: The name of the output txt file. 27 | * @param [in] num_per_line: number of matrix elements per line. 28 | */ 29 | void write_matrices_to_txt(vector &Mat, const string &fname, 30 | size_t num_per_line = 5); 31 | 32 | /** 33 | * @brief Read a vector of matrices from a txt file generated from 34 | * matrix::write_matrices_to_txt(). 35 | * 36 | * @param [in] fname: the name (relative or absolute path) of the matrix txt 37 | * file. 38 | * @return std::vector>: a vector of matrices. 39 | * @see matrix::write_matrices_to_txt() 40 | */ 41 | std::vector read_matrices_from_txt(const string &fname); 42 | 43 | } // namespace test 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /tests/psi4_losc/test_frac_scf.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test code for the extended SCF procedure, `psi4_losc.scf.scf()` for fractional 3 | systems. 4 | """ 5 | 6 | import unittest 7 | import psi4 8 | import numpy as np 9 | from psi4_losc.scf import scf 10 | 11 | psi4.core.be_quiet() 12 | 13 | 14 | class TestSelfSCFFractional(unittest.TestCase): 15 | def setUp(self): 16 | self.mol_H = psi4.geometry(""" 17 | 0 2 18 | H 19 | symmetry c1 20 | """, name="H") 21 | self.mol_H2_plus = psi4.geometry(""" 22 | 1 2 23 | H 24 | H 1 1.2 25 | symmetry c1 26 | """, name="H2+") 27 | 28 | psi4.set_options({'guess': 'core', 29 | 'basis': '3-21g', 30 | 'scf_type': 'direct', 31 | 'e_convergence': 1e-8, 32 | 'maxiter': 50}) 33 | 34 | def test_EN_curve_H_gs_HF(self): 35 | """ 36 | Test the ground state of E(N) curve of one-electron system: H atom from HF. 37 | In this case, HF results are exact. 38 | """ 39 | print( 40 | "\n==> Test the ground state E(N) curve of H atom in [0, 1]:") 41 | print(" method=HF, guess=core, basis=3-21g, scf_type=DF") 42 | psi4.core.set_active_molecule(self.mol_H) 43 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 44 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 45 | 46 | name = 'hf' 47 | E_0 = scf(name, occ={'alpha': {'homo': 0}}).energy() 48 | E_1 = scf(name, occ={'alpha': {'homo': 1}}).energy() 49 | 50 | def ref_E_n(n): 51 | return (E_1 - E_0) * n + E_0 52 | for n in np.arange(0, 1, 0.1): 53 | E_n = scf(name, occ={'alpha': {'homo': n}}).energy() 54 | self.assertAlmostEqual(ref_E_n(n), E_n) 55 | 56 | optstash.restore() 57 | 58 | def test_EN_curve_H_gs_b3lyp(self): 59 | """ 60 | Test the ground state of E(N) curve of one-electron system: H atom from B3LYP. 61 | """ 62 | print( 63 | "\n==> Test the ground state E(N) curve of H atom in [0, 1]:") 64 | print(" method=b3lyp, guess=core, basis=3-21g, scf_type=DF") 65 | psi4.core.set_active_molecule(self.mol_H) 66 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 67 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 68 | 69 | name = 'b3lyp' 70 | # ref comes from self generation. compared with qm4d calculations 71 | # and these results look reasonable. 72 | E_ref = { 73 | 0: 0, 74 | 0.1: -0.06230425262483324, 75 | 0.2: -0.12438454229516446, 76 | 0.3: -0.18386651447939936, 77 | 0.4: -0.24007115938269238, 78 | 0.5: -0.29266784724316897, 79 | 0.6: -0.34147427067192015, 80 | 0.7: -0.38638636474480936, 81 | 0.8: -0.42734614613486516, 82 | 0.9: -0.46432455648727333, 83 | 1.0: -0.4973113890200121, 84 | } 85 | for n, ref in E_ref.items(): 86 | E_n = scf(name, occ={'alpha': {'homo': n}}).energy() 87 | self.assertAlmostEqual(ref, E_n) 88 | 89 | optstash.restore() 90 | 91 | def test_EN_curve_H2_plus_gs_HF(self): 92 | """ 93 | Test the ground state E(N) curve of one-electron system: H2+ atom from HF. 94 | This is a case with multiple atoms. In this case, HF results are exact. 95 | """ 96 | print("\n==> Test the ground state of E(N) curve of H2+ in [0, 1]:") 97 | print(" method=HF, guess=core, basis=3-21g, scf_type=DF") 98 | psi4.core.set_active_molecule(self.mol_H2_plus) 99 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 100 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 101 | 102 | name = 'hf' 103 | E_0 = scf(name, occ={'alpha': {'homo': 0}}).energy() 104 | E_1 = scf(name, occ={'alpha': {'homo': 1}}).energy() 105 | 106 | def ref_E_n(n): 107 | return (E_1 - E_0) * n + E_0 108 | for n in np.arange(0, 1, 0.5): 109 | E_n = scf(name, occ={'alpha': {'homo': n}}).energy() 110 | self.assertAlmostEqual(ref_E_n(n), E_n) 111 | 112 | optstash.restore() 113 | 114 | 115 | if __name__ == '__main__': 116 | unittest.main() 117 | -------------------------------------------------------------------------------- /tests/psi4_losc/test_post_scf_losc.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test code for post-SCF-LOSC calculation, `psi4_losc.post_scf_losc()`. 3 | """ 4 | 5 | import unittest 6 | import psi4 7 | import psi4_losc 8 | from psi4_losc import post_scf_losc 9 | 10 | psi4.core.be_quiet() 11 | 12 | 13 | class TestPostSCFLOSCIntegerAufbau(unittest.TestCase): 14 | """ 15 | Test `psi4_losc.post_scf_losc()` for integer systems with aufbau occupations. 16 | """ 17 | 18 | def setUp(self): 19 | self.mol_H2_1A = psi4.geometry(""" 20 | 0 1 21 | H 22 | H 1 1 23 | symmetry c1 24 | """, name="H2: 1A") 25 | self.mol_H2_10A = psi4.geometry(""" 26 | 0 1 27 | H 28 | H 1 10 29 | symmetry c1 30 | """, name="H2: 10A") 31 | self.mol_H2_plus_1A = psi4.geometry(""" 32 | 1 2 33 | H 34 | H 1 1 35 | symmetry c1 36 | """, name="H2+: 1A") 37 | self.mol_H2_plus_10A = psi4.geometry(""" 38 | 1 2 39 | H 40 | H 1 10 41 | symmetry c1 42 | """, name="H2+: 10A") 43 | self.mol_H2O = psi4.geometry(""" 44 | 0 1 45 | O 0 0 0 46 | H 1 0 0 47 | H 0 1 0 48 | symmetry c1 49 | """, name="H2O") 50 | 51 | psi4.set_options({'guess': 'core', 52 | 'basis': '6-31g', 53 | 'scf_type': 'df', 54 | 'e_convergence': 1e-8, 55 | 'maxiter': 100}) 56 | psi4_losc.options.set_param('curvature', 'df_molecular_fragment_size', 1) 57 | psi4_losc.options.set_param('curvature', 'df_basis', '6-31g') 58 | 59 | def run_mol_no_correction(self, mol, precision=7): 60 | """ 61 | Test cases in which LOSC gives no corrections. Compare the total energy 62 | between `psi4_losc.post_scf_losc()` and `psi4.energy()`. Three 63 | representative DFAs, svwn, blyp and b3lyp, are used for test. 64 | """ 65 | psi4.core.set_active_molecule(mol) 66 | dfa_info = {'svwn': psi4_losc.SVWN, 67 | 'blyp': psi4_losc.BLYP, 68 | 'b3lyp': psi4_losc.B3LYP} 69 | for dfa in 'svwn blyp b3lyp'.split(): 70 | print(f' Test mol {mol.name()}: dfa={dfa}') 71 | E_ref, dfa_wfn = psi4.energy(dfa, return_wfn=True) 72 | E_calc, _ = post_scf_losc(dfa_info[dfa], dfa_wfn) 73 | E_calc_2, _ = post_scf_losc( 74 | dfa_info[dfa], dfa_wfn, window=[-30, 10]) 75 | self.assertAlmostEqual(E_ref, E_calc, places=precision) 76 | self.assertAlmostEqual(E_ref, E_calc_2, places=precision) 77 | 78 | def run_mol_correction(self, mol, E_ref, orb_ref, precision=4): 79 | """ 80 | Test cases in which LOSC gives corrections. Compare the total energy 81 | between `psi4_losc.post_scf_losc()` and an estimated reference results. 82 | The estimated references are taken from qm4d calculations. Only use 83 | b3lyp functional for test. 84 | """ 85 | psi4.core.set_active_molecule(mol) 86 | _, dfa_wfn = psi4.energy('b3lyp', return_wfn=True) 87 | E_calc, orb_calc = post_scf_losc(psi4_losc.B3LYP, dfa_wfn) 88 | print(f' Test mol {mol.name()}: dfa=b3lyp, E_losc={E_calc}') 89 | self.assertAlmostEqual(E_ref, E_calc) 90 | for i in range(len(orb_ref)): 91 | self.assertAlmostEqual(orb_ref[i], orb_calc[0][i], places=3) 92 | psi4.core.clean() 93 | 94 | def test_uks_open_shell(self): 95 | """ 96 | Test unrestricted calculations for open shell cases. 97 | """ 98 | print("\n==> Test UKS Open Shell") 99 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE'], 100 | ['SCF', 'SCF_TYPE']) 101 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 102 | psi4.core.set_local_option('SCF', 'SCF_TYPE', 'DIRECT') 103 | 104 | # LO = CO 105 | self.run_mol_no_correction(self.mol_H2_plus_1A) 106 | 107 | # LO != CO 108 | # Take from psi4_losc.post_scf_losc() self. Compared to qm4d output and 109 | # it is close to the 4-th digit. 110 | E_ref = -0.5008660792943231 111 | orb_ref = [-15.3096, -13.8701, 15.5803, 15.5803] 112 | self.run_mol_correction(self.mol_H2_plus_10A, E_ref, orb_ref) 113 | 114 | optstash.restore() 115 | 116 | def test_uks_close_shell(self): 117 | """ 118 | Test unrestricted calculations for close shell cases. 119 | """ 120 | print("\n==> Test UKS Close Shell") 121 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE'], 122 | ['SCF', 'SCF_TYPE']) 123 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 124 | psi4.core.set_local_option('SCF', 'SCF_TYPE', 'DIRECT') 125 | 126 | # LO = CO 127 | self.run_mol_no_correction(self.mol_H2_1A) 128 | 129 | # LO != CO 130 | E_ref = -0.7580725182673166 131 | orb_ref = [-6.9866, -5.5466, 24.0436, 24.0436] 132 | self.run_mol_correction(self.mol_H2_10A, E_ref, orb_ref) 133 | 134 | optstash.restore() 135 | 136 | def test_rks_close_shell(self): 137 | """ 138 | Test restricted calculations for close shell cases. 139 | """ 140 | print("\n==> Test RKS Close Shell") 141 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE'], 142 | ['SCF', 'SCF_TYPE']) 143 | psi4.core.set_local_option('SCF', 'REFERENCE', 'RHF') 144 | psi4.core.set_local_option('SCF', 'SCF_TYPE', 'DIRECT') 145 | 146 | # LO = CO 147 | self.run_mol_no_correction(self.mol_H2_1A) 148 | 149 | # LO != CO 150 | E_ref = -0.75807251826734256 151 | orb_ref = [-6.9866, -5.5466, 24.0436, 24.0436] 152 | self.run_mol_correction(self.mol_H2_10A, E_ref, orb_ref) 153 | 154 | optstash.restore() 155 | 156 | 157 | if __name__ == '__main__': 158 | unittest.main() 159 | -------------------------------------------------------------------------------- /tests/psi4_losc/test_scf.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test code for the extended SCF procedure, `psi4_losc.scf.scf()` for integer 3 | systems. 4 | """ 5 | 6 | import unittest 7 | import psi4 8 | from psi4_losc.scf import scf 9 | 10 | psi4.core.be_quiet() 11 | 12 | class TestSelfSCFIntegerAufbau(unittest.TestCase): 13 | """ 14 | Test `psi4_losc.scf.scf()` for integer systems with aufbau occupations. 15 | """ 16 | def setUp(self): 17 | self.mol_H = psi4.geometry(""" 18 | 0 2 19 | H 20 | symmetry c1 21 | """, name="H") 22 | self.mol_H_plus = psi4.geometry(""" 23 | 1 1 24 | H 25 | symmetry c1 26 | """, name="H+") 27 | self.mol_H2 = psi4.geometry(""" 28 | 0 1 29 | H 30 | H 1 1.2 31 | symmetry c1 32 | """, name="H2") 33 | self.mol_H2_plus = psi4.geometry(""" 34 | 1 2 35 | H 36 | H 1 1.2 37 | symmetry c1 38 | """, name="H2+") 39 | self.mol_H2O = psi4.geometry(""" 40 | 0 1 41 | O 0 0 0 42 | H 1 0 0 43 | H 0 1 0 44 | symmetry c1 45 | """, name="H2O") 46 | self.mol_H2O_plus = psi4.geometry(""" 47 | 1 2 48 | O 0 0 0 49 | H 1 0 0 50 | H 0 1 0 51 | symmetry c1 52 | """, name="H2O+") 53 | 54 | psi4.set_options({'guess': 'core', 55 | 'basis': '3-21g', 56 | 'scf_type': 'df', 57 | 'e_convergence': 1e-8, 58 | 'maxiter': 100}) 59 | 60 | def run_mol(self, mol, precision=7): 61 | """ 62 | Compare the total energy between `psi4_losc.scf.scf()` and `psi4.energy()`. 63 | Three representative DFAs, svwn, blyp and b3lyp, are used for test. 64 | """ 65 | psi4.core.set_active_molecule(mol) 66 | for dfa in 'hf svwn blyp b3lyp'.split(): 67 | print(f' Test mol {mol.name()}: dfa={dfa}') 68 | E_ref = psi4.energy(dfa) 69 | wfn = scf(dfa) 70 | self.assertAlmostEqual(E_ref, wfn.energy(), places=precision) 71 | psi4.core.clean() 72 | 73 | def test_H_plus(self): 74 | """ 75 | Test a very special case, H+, just a naked nuclear. The results should 76 | be zero. 77 | """ 78 | print("\n==> Test H+: just a naked nuclear") 79 | self.run_mol(self.mol_H_plus) 80 | 81 | def test_uks_open_shell(self): 82 | """ 83 | Test unrestricted calculations for open shell cases. 84 | """ 85 | print("\n==> Test UKS Open Shell") 86 | optstash = psi4.driver.p4util.OptionsState( 87 | ['SCF', 'REFERENCE'], 88 | ['SCF', 'D_CONVERGENCE'], 89 | ) 90 | psi4.core.set_local_option('SCF', 'REFERENCE','UHF') 91 | psi4.core.set_local_option('SCF', 'D_CONVERGENCE', 1.0e-4) 92 | 93 | self.run_mol(self.mol_H) 94 | self.run_mol(self.mol_H2_plus) 95 | self.run_mol(self.mol_H2O_plus, precision=5) 96 | 97 | optstash.restore() 98 | 99 | def test_uks_close_shell(self): 100 | """ 101 | Test unrestricted calculations for close shell cases. 102 | """ 103 | print("\n==> Test UKS Close Shell") 104 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 105 | psi4.core.set_local_option('SCF', 'REFERENCE','UHF') 106 | 107 | self.run_mol(self.mol_H2) 108 | self.run_mol(self.mol_H2O) 109 | 110 | optstash.restore() 111 | def test_rks_close_shell(self): 112 | """ 113 | Test restricted calculations for close shell cases. 114 | """ 115 | print("\n==> Test RKS Close Shell") 116 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 117 | psi4.core.set_local_option('SCF', 'REFERENCE','RHF') 118 | self.run_mol(self.mol_H2) 119 | self.run_mol(self.mol_H2O) 120 | 121 | optstash.restore() 122 | 123 | 124 | if __name__ == '__main__': 125 | unittest.main() 126 | -------------------------------------------------------------------------------- /tests/psi4_losc/test_scf_losc.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test code for SCF-LOSC (frozen-LO) calculations. 3 | """ 4 | 5 | import unittest 6 | import psi4_losc 7 | import psi4 8 | from psi4_losc import scf_losc 9 | from psi4_losc.scf import scf_losc as my_scf_losc 10 | 11 | psi4.core.be_quiet() 12 | 13 | 14 | class TestSCFLOSCIntegerAufbau(unittest.TestCase): 15 | """ 16 | Test `psi4_losc.scf_losc()` for integer systems with aufbau occupations. 17 | """ 18 | 19 | def setUp(self): 20 | self.mol_H2_1A = psi4.geometry(""" 21 | 0 1 22 | H 23 | H 1 1 24 | symmetry c1 25 | """, name="H2: 1A") 26 | self.mol_H2_10A = psi4.geometry(""" 27 | 0 1 28 | H 29 | H 1 10 30 | symmetry c1 31 | """, name="H2: 10A") 32 | self.mol_H2_plus_1A = psi4.geometry(""" 33 | 1 2 34 | H 35 | H 1 1 36 | symmetry c1 37 | """, name="H2+: 1A") 38 | self.mol_H2_plus_10A = psi4.geometry(""" 39 | 1 2 40 | H 41 | H 1 1 42 | symmetry c1 43 | """, name="H2+: 10A") 44 | self.mol_H2O = psi4.geometry(""" 45 | 0 1 46 | O 0 0 0 47 | H 1 0 0 48 | H 0 1 0 49 | symmetry c1 50 | """, name="H2O") 51 | 52 | psi4.set_options({'guess': 'core', 53 | 'basis': '6-31g', 54 | 'scf_type': 'df', 55 | 'e_convergence': 1e-8, 56 | 'maxiter': 100}) 57 | 58 | def run_mol_no_correction(self, mol, precision=7): 59 | """ 60 | Test cases in which LOSC gives no corrections. Compare the total energy 61 | between `psi4_losc.scf_losc()` and `psi4.energy()`. Three representative 62 | DFAs, svwn, blyp and b3lyp, are used for test. 63 | """ 64 | psi4.core.set_active_molecule(mol) 65 | dfa_info = {'svwn': psi4_losc.SVWN, 66 | 'blyp': psi4_losc.BLYP, 67 | 'b3lyp': psi4_losc.B3LYP} 68 | for dfa in 'svwn blyp b3lyp'.split(): 69 | print(f' Test mol {mol.name()}: dfa={dfa}') 70 | E_ref, dfa_wfn = psi4.energy(dfa, return_wfn=True) 71 | E_calc = scf_losc(dfa_info[dfa], dfa_wfn).energy() 72 | my_E_calc = my_scf_losc(dfa_info[dfa], dfa_wfn).energy() 73 | self.assertAlmostEqual(E_ref, E_calc, places=precision) 74 | self.assertAlmostEqual(my_E_calc, E_calc, places=precision) 75 | psi4.core.clean() 76 | 77 | def test_uks_open_shell(self): 78 | """ 79 | Test unrestricted calculations for open shell cases. 80 | """ 81 | print("\n==> Test UKS Open Shell") 82 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 83 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 84 | 85 | # LO = CO 86 | self.run_mol_no_correction(self.mol_H2_plus_1A) 87 | 88 | # TODO: LO != CO 89 | 90 | optstash.restore() 91 | 92 | def test_uks_close_shell(self): 93 | """ 94 | Test unrestricted calculations for close shell cases. 95 | """ 96 | print("\n==> Test UKS Close Shell") 97 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 98 | psi4.core.set_local_option('SCF', 'REFERENCE', 'UHF') 99 | 100 | # LO = CO 101 | self.run_mol_no_correction(self.mol_H2_1A) 102 | 103 | # TODO: LO != CO 104 | 105 | optstash.restore() 106 | 107 | def test_rks_close_shell(self): 108 | """ 109 | Test restricted calculations for close shell cases. 110 | """ 111 | print("\n==> Test RKS Close Shell") 112 | optstash = psi4.driver.p4util.OptionsState(['SCF', 'REFERENCE']) 113 | psi4.core.set_local_option('SCF', 'REFERENCE', 'RHF') 114 | 115 | # LO = CO 116 | self.run_mol_no_correction(self.mol_H2_1A) 117 | 118 | # TODO: LO != CO 119 | 120 | optstash.restore() 121 | 122 | 123 | if __name__ == '__main__': 124 | unittest.main() 125 | --------------------------------------------------------------------------------