diff --git a/.github/actions/build-wheel/entrypoint.sh b/.github/actions/build-wheel/entrypoint.sh index ba23bc37..b4dbb8af 100755 --- a/.github/actions/build-wheel/entrypoint.sh +++ b/.github/actions/build-wheel/entrypoint.sh @@ -21,6 +21,8 @@ elif [ "${PYTHON_VERSION}" = "3.11" ]; then PY_VER=cp311-cp311 elif [ "${PYTHON_VERSION}" = "3.12" ]; then PY_VER=cp312-cp312 +elif [ "${PYTHON_VERSION}" = "3.13-dev" ]; then + PY_VER=cp313-cp313 fi PY_EXE=/opt/python/"${PY_VER}"/bin/python3 @@ -31,12 +33,13 @@ ls -l /opt/python /opt/python/"${PY_VER}"/bin/pip install --upgrade --no-cache-dir pip setuptools /opt/python/"${PY_VER}"/bin/pip install --no-cache-dir mkl==2021.4 mkl-include intel-openmp numpy 'cmake>=3.19' pybind11==2.12.0 $(cat $(which auditwheel) | head -1 | awk -F'!' '{print $2}') -m pip install auditwheel==5.1.2 +$(cat $(which auditwheel) | head -1 | awk -F'!' '{print $2}') -m pip install setuptools if [ "${PARALLEL}" = "mpi" ]; then yum install -y wget openssh-clients openssh-server - wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.6.tar.gz - tar zxf openmpi-4.1.6.tar.gz - cd openmpi-4.1.6 + wget https://download.open-mpi.org/release/open-mpi/v5.0/openmpi-5.0.5.tar.gz + tar zxf openmpi-5.0.5.tar.gz + cd openmpi-5.0.5 ./configure --prefix=/usr/local |& tee config.out make -j 4 |& tee make.out make install |& tee install.out diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index acd0922f..ef7acd00 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,12 +23,14 @@ jobs: strategy: matrix: - os: [ ubuntu-20.04, macos-12, windows-2022 ] - python: [ 3.12 ] + os: [ ubuntu-20.04, macos-13, macos-14, windows-2022 ] + python: [ '3.13-dev' ] plat: [ x86_64 ] - parallel: [ mpi, serial, serial-pytest, any-symm-pytest ] + parallel: [ mpi, serial, serial-pytest, any-symm-pytest, main-test ] exclude: - - os: macos-12 + - os: macos-13 + parallel: mpi + - os: macos-14 parallel: mpi - os: windows-2022 parallel: mpi @@ -41,13 +43,19 @@ jobs: python-version: ${{ matrix.python }} - name: install requirements (linux / macos) - if: matrix.os == 'macos-12' || matrix.os == 'ubuntu-20.04' + if: matrix.os == 'macos-13' || matrix.os == 'ubuntu-20.04' env: MKLROOT: ~/.local run: | python -m pip install pip build twine setuptools --upgrade python -m pip install mkl==2021.4 mkl-include intel-openmp numpy 'cmake>=3.19' pybind11==2.12.0 + - name: install requirements (linux / macos) + if: matrix.os == 'macos-14' + run: | + python -m pip install pip build twine setuptools --upgrade + python -m pip install numpy 'cmake>=3.19' pybind11==2.12.0 + - name: install requirements (linux / mpi) if: matrix.parallel == 'mpi' && matrix.os == 'ubuntu-20.04' run: | @@ -110,7 +118,7 @@ jobs: getconf LONG_BIT - name: build gtest (macos) - if: matrix.os == 'macos-12' + if: matrix.os == 'macos-13' env: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: | @@ -123,11 +131,25 @@ jobs: brew install libomp cp /usr/local/opt/libomp/include/*.h /usr/local/include/ + - name: build gtest (macos) + if: matrix.os == 'macos-14' + env: + GTESTROOT: ~/gtest + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 + run: | + git clone -b release-1.8.0 https://github.com/google/googletest + cd googletest + cmake CMakeLists.txt -DCMAKE_INSTALL_PREFIX=${GTESTROOT} + make + make install + brew update + brew install libomp + - name: build test (serial-pytest, linux | macos) - if: matrix.parallel == 'serial-pytest' && (matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-12') + if: (matrix.parallel == 'serial-pytest' || matrix.parallel == 'main-test') && (matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13') env: MKLROOT: ~/.local - MACOSX_DEPLOYMENT_TARGET: '10.9' + MACOSX_DEPLOYMENT_TARGET: '11.0' CC: gcc-9 CXX: g++-9 run: | @@ -137,8 +159,24 @@ jobs: cmake .. -DUSE_MKL=ON -DBUILD_LIB=ON -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SG=ON make -j 2 + - name: build test (serial-pytest, macos-arm64) + if: (matrix.parallel == 'serial-pytest' || matrix.parallel == 'main-test') && matrix.os == 'macos-14' + env: + MACOSX_DEPLOYMENT_TARGET: '11.0' + CC: gcc-9 + CXX: g++-9 + run: | + mkdir build + cd build + cmake --version + export OMPROOT=$(brew --prefix libomp) + cmake .. -DUSE_MKL=OFF -DARCH_ARM64=ON -DCMAKE_CXX_FLAGS=-I${OMPROOT}/include -DOMP_LIB=OMP \ + -DBUILD_LIB=ON -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SG=ON -DFORCE_LIB_ABS_PATH=OFF \ + -DAPPLE_ACC_SINGLE_PREC=OFF + make -j 2 + - name: build test (serial-pytest, windows) - if: matrix.parallel == 'serial-pytest' && matrix.os == 'windows-2022' + if: (matrix.parallel == 'serial-pytest' || matrix.parallel == 'main-test') && matrix.os == 'windows-2022' env: BLAS_ROOT: D:\a\openblas run: | @@ -150,10 +188,10 @@ jobs: cmake --build . -j 2 --config Release -- '/v:d' - name: build test (any-symm-pytest, linux | macos) - if: matrix.parallel == 'any-symm-pytest' && (matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-12') + if: matrix.parallel == 'any-symm-pytest' && (matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13') env: MKLROOT: ~/.local - MACOSX_DEPLOYMENT_TARGET: '10.9' + MACOSX_DEPLOYMENT_TARGET: '11.0' CC: gcc-9 CXX: g++-9 run: | @@ -163,6 +201,22 @@ jobs: cmake .. -DUSE_MKL=ON -DBUILD_LIB=ON -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SU2SZ=OFF -DUSE_SANY=ON make -j 2 + - name: build test (any-symm-pytest, macos-arm64) + if: matrix.parallel == 'any-symm-pytest' && matrix.os == 'macos-14' + env: + MACOSX_DEPLOYMENT_TARGET: '11.0' + CC: gcc-9 + CXX: g++-9 + run: | + mkdir build + cd build + cmake --version + export OMPROOT=$(brew --prefix libomp) + cmake .. -DUSE_MKL=OFF -DARCH_ARM64=ON -DCMAKE_CXX_FLAGS=-I${OMPROOT}/include -DBUILD_LIB=ON -DOMP_LIB=OMP \ + -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SU2SZ=OFF -DUSE_SANY=ON -DFORCE_LIB_ABS_PATH=OFF \ + -DAPPLE_ACC_SINGLE_PREC=OFF + make -j 2 + - name: build test (any-symm-pytest, windows) if: matrix.parallel == 'any-symm-pytest' && matrix.os == 'windows-2022' env: @@ -201,10 +255,10 @@ jobs: make -j 2 - name: build test (serial, macos) - if: matrix.parallel == 'serial' && matrix.os == 'macos-12' + if: matrix.parallel == 'serial' && matrix.os == 'macos-13' env: MKLROOT: ~/.local - MACOSX_DEPLOYMENT_TARGET: '10.9' + MACOSX_DEPLOYMENT_TARGET: '11.0' run: | mkdir build_test cd build_test @@ -212,6 +266,21 @@ jobs: cmake .. -DUSE_MKL=ON -DBUILD_TEST=ON -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SINGLE_PREC=ON -DUSE_SG=ON make -j 2 + - name: build test (serial, macos-arm64) + if: matrix.parallel == 'serial' && matrix.os == 'macos-14' + env: + GTESTROOT: ~/gtest + MACOSX_DEPLOYMENT_TARGET: '11.0' + run: | + mkdir build_test + cd build_test + cmake --version + export OMPROOT=$(brew --prefix libomp) + cmake .. -DUSE_MKL=OFF -DARCH_ARM64=ON -DCMAKE_CXX_FLAGS=-I${OMPROOT}/include -DBUILD_TEST=ON -DOMP_LIB=OMP \ + -DLARGE_BOND=ON -DUSE_COMPLEX=ON -DUSE_SINGLE_PREC=OFF -DUSE_SG=ON -DGTEST_ROOT=${GTESTROOT} \ + -DFORCE_LIB_ABS_PATH=OFF -DSIMPLE_TEST=ON + make -j 2 + - name: run test (serial, windows) if: matrix.parallel == 'serial' && matrix.os == 'windows-2022' env: @@ -238,7 +307,7 @@ jobs: ./block2_tests - name: run test (serial, macos) - if: matrix.parallel == 'serial' && matrix.os == 'macos-12' + if: matrix.parallel == 'serial' && (matrix.os == 'macos-13' || matrix.os == 'macos-14') run: | cd build_test ./block2_tests @@ -250,7 +319,7 @@ jobs: run: | $vcpath = Get-ChildItem 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC' $dumpbin = "$($vcpath[0].FullName)\bin\Hostx64\x64\dumpbin.exe" - & $dumpbin /DEPENDENTS .\build\Release\block2.cp312-win_amd64.pyd + & $dumpbin /DEPENDENTS .\build\Release\block2.cp313-win_amd64.pyd $xpwd = Get-Location $env:PYTHONPATH = "${xpwd};${xpwd}\build\Release;" + $env:PYTHONPATH $env:PATH = "${env:BLAS_ROOT}\bin;" + $env:PATH @@ -263,7 +332,7 @@ jobs: - name: run test (serial-pytest, linux) if: matrix.parallel == 'serial-pytest' && matrix.os == 'ubuntu-20.04' run: | - python -m pip install pytest 'pyscf==2.5.0' 'scipy==1.12.0' + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} export CPUTYPE=$(lscpu | grep 'Vendor ID' | awk '{print $3}') if [ "$CPUTYPE" = "AuthenticAMD" ]; then @@ -273,12 +342,54 @@ jobs: py.test -s pyblock2/unit_test/*.py - name: run test (serial-pytest, macos) - if: matrix.parallel == 'serial-pytest' && matrix.os == 'macos-12' + if: matrix.parallel == 'serial-pytest' && (matrix.os == 'macos-13' || matrix.os == 'macos-14') run: | - python -m pip install pytest 'pyscf==2.5.0' 'scipy==1.12.0' + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} py.test -s pyblock2/unit_test/*.py + - name: run test (main-test, windows) + if: matrix.parallel == 'main-test' && matrix.os == 'windows-2022' + env: + BLAS_ROOT: D:\a\openblas + run: | + $vcpath = Get-ChildItem 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC' + $dumpbin = "$($vcpath[0].FullName)\bin\Hostx64\x64\dumpbin.exe" + & $dumpbin /DEPENDENTS .\build\Release\block2.cp313-win_amd64.pyd + $xpwd = Get-Location + $env:PYTHONPATH = "${xpwd};${xpwd}\build\Release;" + $env:PYTHONPATH + $env:PATH = "${env:BLAS_ROOT}\bin;" + $env:PATH + $env:PATH = "${env:Python_ROOT_DIR}\Library\bin;" + $env:PATH + $env:PATH = "${env:Python_ROOT_DIR};" + $env:PATH + $env:PATH = "$($vcpath[0].FullName)\bin\Hostx64\x64;" + $env:PATH + $env:block2main = "${xpwd}\pyblock2\driver\block2main" + python -m pip install 'scipy==1.14.1' + cd pyblock2\main_test + .\run-test.ps1 + + - name: run test (main-test, linux) + if: matrix.parallel == 'main-test' && matrix.os == 'ubuntu-20.04' + run: | + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' + export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} + export PATH=$(pwd)/pyblock2/driver:$PATH + export CPUTYPE=$(lscpu | grep 'Vendor ID' | awk '{print $3}') + if [ "$CPUTYPE" = "AuthenticAMD" ]; then + export LD_PRELOAD=$PWD/libfixcpu.so + fi + echo $LD_PRELOAD + cd pyblock2/main_test + ./run-test.sh + + - name: run test (main-test, macos) + if: matrix.parallel == 'main-test' && (matrix.os == 'macos-13' || matrix.os == 'macos-14') + run: | + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' + export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} + export PATH=$(pwd)/pyblock2/driver:$PATH + cd pyblock2/main_test + ./run-test.sh + - name: run test (any-symm-pytest, windows) if: matrix.parallel == 'any-symm-pytest' && matrix.os == 'windows-2022' env: @@ -286,7 +397,7 @@ jobs: run: | $vcpath = Get-ChildItem 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC' $dumpbin = "$($vcpath[0].FullName)\bin\Hostx64\x64\dumpbin.exe" - & $dumpbin /DEPENDENTS .\build\Release\block2.cp312-win_amd64.pyd + & $dumpbin /DEPENDENTS .\build\Release\block2.cp313-win_amd64.pyd $xpwd = Get-Location $env:PYTHONPATH = "${xpwd};${xpwd}\build\Release;" + $env:PYTHONPATH $env:PATH = "${env:BLAS_ROOT}\bin;" + $env:PATH @@ -299,7 +410,7 @@ jobs: - name: run test (any-symm-pytest, linux) if: matrix.parallel == 'any-symm-pytest' && matrix.os == 'ubuntu-20.04' run: | - python -m pip install pytest 'pyscf==2.5.0' 'scipy==1.12.0' + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} export CPUTYPE=$(lscpu | grep 'Vendor ID' | awk '{print $3}') if [ "$CPUTYPE" = "AuthenticAMD" ]; then @@ -309,9 +420,9 @@ jobs: py.test -s pyblock2/unit_test/*.py --symm sany - name: run test (any-symm-pytest, macos) - if: matrix.parallel == 'any-symm-pytest' && matrix.os == 'macos-12' + if: matrix.parallel == 'any-symm-pytest' && (matrix.os == 'macos-13' || matrix.os == 'macos-14') run: | - python -m pip install pytest 'pyscf==2.5.0' 'scipy==1.12.0' + python -m pip install pytest 'pyscf==2.6.2' 'scipy==1.14.1' export PYTHONPATH=$(pwd)/build:$(pwd):${PYTHONPATH} py.test -s pyblock2/unit_test/*.py --symm sany @@ -342,14 +453,22 @@ jobs: strategy: matrix: - os: [ ubuntu-20.04, macos-12, windows-2022 ] - python: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ] + os: [ ubuntu-20.04, macos-13, windows-2022, macos-14 ] + python: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13-dev' ] manylinux: [ 2014 ] plat: [ x86_64, arm64 ] parallel: [ mpi, serial ] exclude: - - os: macos-12 + - os: macos-13 + parallel: mpi + - os: macos-14 parallel: mpi + - os: macos-13 + plat: arm64 + - os: macos-14 + plat: x86_64 + - os: macos-14 + python: '3.7' - os: ubuntu-20.04 plat: arm64 - os: windows-2022 @@ -365,7 +484,7 @@ jobs: python-version: ${{ matrix.python }} - name: install requirements (linux / macos) - if: matrix.os == 'macos-12' || matrix.os == 'ubuntu-20.04' + if: matrix.os == 'macos-13' || matrix.os == 'ubuntu-20.04' env: MKLROOT: ~/.local run: | @@ -373,6 +492,15 @@ jobs: python -m pip install pip build twine setuptools --upgrade python -m pip install mkl==2021.4 mkl-include intel-openmp numpy 'cmake>=3.19' pybind11==2.12.0 + - name: install requirements (linux / macos) + if: matrix.os == 'macos-14' + env: + MKLROOT: ~/.local + run: | + export PYT=$(which python) + python -m pip install pip build twine setuptools --upgrade + python -m pip install numpy 'cmake>=3.19' pybind11==2.12.0 + - name: install requirements (windows) if: matrix.os == 'windows-2022' env: @@ -413,10 +541,10 @@ jobs: delvewheel repair "$($rr[0].FullName)" -v -w dist - name: build wheels (macos-x86_64) - if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'macos-12' && matrix.plat == 'x86_64' + if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'macos-13' && matrix.plat == 'x86_64' env: TAG_STRING: ${{ github.event.ref }} - MACOSX_DEPLOYMENT_TARGET: '10.9' + MACOSX_DEPLOYMENT_TARGET: '11.0' HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: | brew update @@ -446,7 +574,7 @@ jobs: delocate-wheel -k dist/*.whl - name: build wheels (macos-arm64) - if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'macos-12' && matrix.plat == 'arm64' + if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'macos-14' && matrix.plat == 'arm64' env: TAG_STRING: ${{ github.event.ref }} MACOSX_DEPLOYMENT_TARGET: '11.0' @@ -454,29 +582,23 @@ jobs: run: | brew update brew install libomp - cp /usr/local/opt/libomp/include/*.h /usr/local/include/ brew install gnu-sed - export PATH=/usr/local/opt/gnu-sed/bin:$PATH + export PATH=/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH echo ${TAG_STRING:11} + export OMPROOT=$(brew --prefix libomp) + echo ${OMPROOT} gsed -i "s/version=.*/version='${TAG_STRING:11}',/" setup.py gsed -i "/DUSE_MKL/a \ '-DOMP_LIB=OMP'," setup.py gsed -i "/DUSE_MKL/a \ '-DARCH_ARM64=ON'," setup.py gsed -i "/DUSE_MKL/a \ '-DFORCE_LIB_ABS_PATH=OFF'," setup.py + gsed -i "/DUSE_MKL/a \ '-DCMAKE_CXX_FLAGS=-I${OMPROOT}/include'," setup.py gsed -i "/mkl/d" setup.py gsed -i "/intel-openmp/d" setup.py gsed -i "/DUSE_MKL/c \ '-DUSE_MKL=OFF'," setup.py - git clone https://github.com/Homebrew/brew arm-brew - cd arm-brew && git checkout 3.6.16 && cd .. - ./arm-brew/bin/brew update - OMPGZ=$(./arm-brew/bin/brew fetch --force --bottle-tag=arm64_monterey libomp | grep "Downloaded to" | awk '{print $3}') - ./arm-brew/bin/brew install ${OMPGZ} - export OMPROOT=$(./arm-brew/bin/brew --prefix libomp) - echo ${OMPROOT} cmake --version python -m pip install wheel delocate==0.10.7 - export _PYTHON_HOST_PLATFORM="macosx-12.0-arm64" - export SDKROOT=/Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk - export CROSS_COMPILE=1 + export _PYTHON_HOST_PLATFORM="macosx-14.0-arm64" + export SDKROOT=/Applications/Xcode_14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk export PLAT="arm64" python -m pip wheel . -w ./dist --no-deps delocate-wheel --require-archs=arm64 -k dist/*.whl @@ -523,7 +645,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: '3.13-dev' - name: build source dist (serial) env: @@ -585,7 +707,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: '3.13-dev' - name: build source dist (serial) env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 8879d231..5f221096 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,9 @@ OPTION(BUILD_EXE "Build executable block2" OFF) OPTION(REUSE_OBJS "Reuse core objects" ON) OPTION(USE_PCH "Build precompiled headers" ON) OPTION(FORCE_LIB_ABS_PATH "Using absolute path when linking libraries" ON) -# For BUILD_CLIB, local static variables may vaiolate ODR in .so and .exe. +# For BUILD_CLIB, local static variables may violate ODR in .so and .exe. OPTION(USE_GLOBAL_VARIABLE "Use global variable instead of local static ones" ON) +OPTION(SIMPLE_TEST "Only compile basic unit tests" OFF) IF (NOT ${USE_DMRG}) SET(USE_BIG_SITE OFF) @@ -785,7 +786,11 @@ IF (${BUILD_TEST}) FIND_PACKAGE(GTest REQUIRED) INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS}) - FILE(GLOB TSRCS unit_test/test_*.cpp) + IF (${SIMPLE_TEST}) + FILE(GLOB TSRCS unit_test/test_wick_*.cpp unit_test/test_npdm_*.cpp unit_test/test_dmrg_*.cpp) + ELSE() + FILE(GLOB TSRCS unit_test/test_*.cpp) + ENDIF() MESSAGE(STATUS "TSRCS = ${TSRCS}") IF ((NOT APPLE) AND (NOT WIN32)) diff --git a/README.md b/README.md index 1bd55781..31860562 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,11 @@ One can install ``block2`` using ``pip`` (note: for very new Python versions, th pip install block2 -* Hybrid openMP/MPI version (requiring openMPI 4.1.x) +* Hybrid openMP/MPI version (requiring openMPI 5.0.x for ``block2-mpi >= 0.5.3`` or 4.1.x for ``block2-mpi <= 0.5.2`` and ``block2-mpi <= 0.5.3rc19``) pip install block2-mpi -* Binary format is prepared via ``pip`` for python 3.7, 3.8, 3.9, 3.10, and 3.11 with macOS (x86 and arm64, no-MPI) or Linux (no-MPI/openMPI). If these binaries have some problems, you can use the ``--no-binary`` option of ``pip`` to force building from source (for example, ``pip install block2 --no-binary block2``). +* Binary format is prepared via ``pip`` for python 3.8, 3.9, 3.10, 3.11, 3.12, and 3.13 with macOS (x86 and arm64, no-MPI), Linux (no-MPI/openMPI), or Windows (x86, no-MPI). If these binaries have some problems, you can use the ``--no-binary`` option of ``pip`` to force building from source (for example, ``pip install block2 --no-binary block2``). * One should only install one of ``block2`` and ``block2-mpi``. ``block2-mpi`` covers all features in ``block2``, but its dependence on mpi library can sometimes be difficult to deal with. Some guidance for resolving environment problems can be found in issue [#7](https://github.com/block-hczhai/block2-preview/issues/7) and [here](https://block2.readthedocs.io/en/latest/user/installation.html#installation-with-anaconda). @@ -59,7 +59,7 @@ One can install ``block2`` using ``pip`` (note: for very new Python versions, th pip install block2== --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/ pip install block2-mpi== --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/ - where ```` can be some development version number like ``0.5.3rc17`` (see https://github.com/block-hczhai/block2-preview/tags for a complete list of version numbers. The letter ``p`` is not needed). To force reinstalling an updated version, you may consider ``pip`` options ``--upgrade --force-reinstall --no-deps --no-cache-dir``. + where ```` can be some development version number like ``0.5.3rc20`` (see https://github.com/block-hczhai/block2-preview/tags for a complete list of version numbers. The letter ``p`` is not needed). To force reinstalling an updated version, you may consider ``pip`` options ``--upgrade --force-reinstall --no-deps --no-cache-dir``. The detailed instructions on manual installation can be found [here](https://block2.readthedocs.io/en/latest/user/installation.html#manual-installation). diff --git a/docs/source/tutorial/custom-hamiltonians.ipynb b/docs/source/tutorial/custom-hamiltonians.ipynb index a36bf9d9..7743cbac 100644 --- a/docs/source/tutorial/custom-hamiltonians.ipynb +++ b/docs/source/tutorial/custom-hamiltonians.ipynb @@ -13,13 +13,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "id": "2FXmEVkEaJxX" }, "outputs": [], "source": [ - "!pip install block2==0.5.3rc17 -qq --progress-bar off --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/" + "!pip install block2==0.5.3 -qq --progress-bar off --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/" ] }, { @@ -29,7 +29,7 @@ }, "source": [ "\n", - "In this tutorial, we provide an example python scripts for performing DMRG using custom Hamiltonians, where the operators and states at local Hilbert space at every site can be redefined. It is also possible to use different local Hilbert space for different sites. New letters can be introduced for representing new operators (the operator name can only be a single lower or upper case character).\n", + "In this tutorial, we provide example python scripts for performing DMRG using custom Hamiltonians, where the operators and states at local Hilbert space at every site can be redefined. It is also possible to use different local Hilbert space for different sites. New letters can be introduced for representing new operators (the operator name can only be a single lower or upper case character).\n", "\n", "Note the following examples are only supposed to work in the Abelian symmetry modes (``SZ``, ``SZ|CPX``, ``SGF``, ``SGFCPX``, ``SAny``, or ``SAny|CPX``) for Abelian symmetries, and non-Abelian symmetry modes (``SAnySU2`` or ``SAnySU2|CPX``) for non-Abelian symmetries, respectively.\n", "\n", @@ -47,7 +47,7 @@ "base_uri": "https://localhost:8080/" }, "id": "XuXZpeFTb5e2", - "outputId": "d92ee9bc-e0e8-40e5-a4ff-a271948703cd" + "outputId": "7aec1a75-4abe-4f10-8c53-1bcb57377505" }, "outputs": [ { @@ -56,33 +56,33 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.167 | E = -6.2256341447 | DW = 2.65116e-16\n", + "Time elapsed = 0.190 | E = -6.2256341447 | DW = 2.65111e-16\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.240 | E = -6.2256341447 | DE = -8.88e-15 | DW = 4.93007e-16\n", + "Time elapsed = 0.252 | E = -6.2256341447 | DE = -1.15e-14 | DW = 4.93010e-16\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.305 | E = -6.2256341447 | DE = 1.78e-15 | DW = 9.66767e-17\n", + "Time elapsed = 0.310 | E = -6.2256341447 | DE = -3.55e-15 | DW = 9.71891e-17\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.367 | E = -6.2256341447 | DE = 1.78e-15 | DW = 1.20251e-16\n", + "Time elapsed = 0.372 | E = -6.2256341447 | DE = 2.66e-15 | DW = 1.20240e-16\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.431 | E = -6.2256341447 | DE = -8.88e-16 | DW = 3.71514e-20\n", + "Time elapsed = 0.454 | E = -6.2256341447 | DE = 1.78e-15 | DW = 3.57827e-20\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.493 | E = -6.2256341447 | DE = -3.55e-15 | DW = 6.52472e-20\n", + "Time elapsed = 0.526 | E = -6.2256341447 | DE = 0.00e+00 | DW = 4.90675e-20\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.560 | E = -6.2256341447 | DE = -1.78e-15 | DW = 4.11603e-20\n", + "Time elapsed = 0.607 | E = -6.2256341447 | DE = 1.78e-15 | DW = 3.06028e-20\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.626 | E = -6.2256341447 | DE = 0.00e+00 | DW = 4.46198e-20\n", + "Time elapsed = 0.675 | E = -6.2256341447 | DE = -4.44e-15 | DW = 4.67630e-20\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 0.674 | E = -6.2256341447 | DE = 7.11e-15 | DW = 4.96657e-20\n", + "Time elapsed = 0.723 | E = -6.2256341447 | DE = 1.78e-15 | DW = 4.23771e-20\n", "\n", - "DMRG energy = -6.225634144657917\n" + "DMRG energy = -6.225634144657920\n" ] } ], @@ -149,7 +149,7 @@ "base_uri": "https://localhost:8080/" }, "id": "JqphdawZboo9", - "outputId": "bf7815ae-6db6-4831-c1ed-fb0cf2ee63d3" + "outputId": "a7e01e75-f9d4-4d98-b7de-61bc424b0f32" }, "outputs": [ { @@ -158,33 +158,33 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 94.146 | E = -6.9568929542 | DW = 3.61640e-09\n", + "Time elapsed = 97.176 | E = -6.9568929233 | DW = 3.61640e-09\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 126.358 | E = -6.9568932112 | DE = -2.57e-07 | DW = 3.01342e-19\n", + "Time elapsed = 128.466 | E = -6.9568932112 | DE = -2.88e-07 | DW = 2.96437e-19\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 139.180 | E = -6.9568932112 | DE = 4.44e-15 | DW = 1.23451e-19\n", + "Time elapsed = 140.826 | E = -6.9568932112 | DE = 1.78e-15 | DW = 1.36334e-19\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 149.110 | E = -6.9568932112 | DE = 1.78e-15 | DW = 7.41629e-20\n", + "Time elapsed = 151.523 | E = -6.9568932112 | DE = -5.33e-15 | DW = 6.91757e-20\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 158.521 | E = -6.9568932112 | DE = 3.55e-15 | DW = 7.71387e-20\n", + "Time elapsed = 163.105 | E = -6.9568932112 | DE = 0.00e+00 | DW = 9.27422e-20\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 166.802 | E = -6.9568932112 | DE = -5.33e-15 | DW = 6.44981e-20\n", + "Time elapsed = 173.000 | E = -6.9568932112 | DE = 3.55e-15 | DW = 6.71055e-20\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 175.980 | E = -6.9568932112 | DE = 8.88e-16 | DW = 8.11423e-20\n", + "Time elapsed = 183.442 | E = -6.9568932112 | DE = 0.00e+00 | DW = 8.23532e-20\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 184.501 | E = -6.9568932112 | DE = -2.66e-15 | DW = 6.41555e-20\n", + "Time elapsed = 192.231 | E = -6.9568932112 | DE = 0.00e+00 | DW = 6.35113e-20\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 192.172 | E = -6.9568932112 | DE = 0.00e+00 | DW = 7.78301e-20\n", + "Time elapsed = 202.099 | E = -6.9568932112 | DE = -3.55e-15 | DW = 7.37915e-20\n", "\n", - "DMRG energy = -6.956893211180857\n" + "DMRG energy = -6.956893211180319\n" ] } ], @@ -272,7 +272,7 @@ "base_uri": "https://localhost:8080/" }, "id": "J2Ed7zljSOLS", - "outputId": "f6f530e3-5270-4c1f-fd38-1dfd599ddb38" + "outputId": "020faaba-aadb-4069-9247-9b5d6af3aada" }, "outputs": [ { @@ -281,33 +281,33 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.247 | E = -6.2256341447 | DW = 5.28457e-16\n", + "Time elapsed = 0.173 | E = -6.2256341447 | DW = 5.28455e-16\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.344 | E = -6.2256341447 | DE = -8.88e-15 | DW = 6.68285e-16\n", + "Time elapsed = 0.242 | E = -6.2256341447 | DE = -2.13e-14 | DW = 6.68292e-16\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.446 | E = -6.2256341447 | DE = -4.44e-15 | DW = 1.63432e-16\n", + "Time elapsed = 0.304 | E = -6.2256341447 | DE = 1.78e-15 | DW = 1.63437e-16\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.543 | E = -6.2256341447 | DE = 1.78e-15 | DW = 2.16706e-16\n", + "Time elapsed = 0.369 | E = -6.2256341447 | DE = 5.33e-15 | DW = 2.16736e-16\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.623 | E = -6.2256341447 | DE = 3.55e-15 | DW = 2.88426e-20\n", + "Time elapsed = 0.443 | E = -6.2256341447 | DE = -5.33e-15 | DW = 5.25972e-20\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.692 | E = -6.2256341447 | DE = -5.33e-15 | DW = 2.28873e-20\n", + "Time elapsed = 0.512 | E = -6.2256341447 | DE = -1.78e-15 | DW = 3.41974e-20\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.764 | E = -6.2256341447 | DE = 8.88e-16 | DW = 3.56876e-20\n", + "Time elapsed = 0.583 | E = -6.2256341447 | DE = 3.55e-15 | DW = 4.52744e-20\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 0.831 | E = -6.2256341447 | DE = 1.78e-15 | DW = 3.86969e-20\n", + "Time elapsed = 0.682 | E = -6.2256341447 | DE = 0.00e+00 | DW = 3.06317e-20\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 0.880 | E = -6.2256341447 | DE = -2.66e-15 | DW = 5.43709e-20\n", + "Time elapsed = 0.755 | E = -6.2256341447 | DE = 0.00e+00 | DW = 5.08352e-20\n", "\n", - "DMRG energy = -6.225634144658391\n" + "DMRG energy = -6.225634144658388\n" ] } ], @@ -375,7 +375,7 @@ "base_uri": "https://localhost:8080/" }, "id": "Sy3eG4KuS9qP", - "outputId": "fbaccccb-0674-412b-c2ea-fdb27476f894" + "outputId": "edd37eff-3a1d-4479-b646-fc2150715cfb" }, "outputs": [ { @@ -384,42 +384,42 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 36.478 | E[ 10] = -6.9958183038 -6.5705972881 -6.5705972845 -6.5705972809 -6.2773135425 -6.2256341359 -6.1122535707 -6.1122534910 -6.1122534358 -6.0320900884 | DW = 4.44265e-09\n", + "Time elapsed = 36.792 | E[ 10] = -6.9958183038 -6.5705972881 -6.5705972845 -6.5705972810 -6.2773135424 -6.2256341358 -6.1122535707 -6.1122534910 -6.1122534359 -6.0320900880 | DW = 4.43209e-09\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 40.236 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -1.62e-07 | DW = 1.12165e-09\n", + "Time elapsed = 40.503 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -1.62e-07 | DW = 1.18662e-09\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 43.608 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 3.43e-12 | DW = 1.18398e-09\n", + "Time elapsed = 43.254 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 2.36e-12 | DW = 1.14924e-09\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 46.245 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -1.75e-12 | DW = 1.12063e-09\n", + "Time elapsed = 46.885 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -3.00e-12 | DW = 1.22182e-09\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 49.844 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -1.88e-12 | DW = 7.51709e-17\n", + "Time elapsed = 50.663 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -2.10e-12 | DW = 8.05373e-17\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 52.386 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -8.88e-15 | DW = 1.55303e-17\n", + "Time elapsed = 53.663 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 2.58e-14 | DW = 1.60312e-17\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 55.928 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 0.00e+00 | DW = 1.59309e-17\n", + "Time elapsed = 56.713 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = -1.07e-14 | DW = 1.92537e-17\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 58.510 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 1.24e-14 | DW = 6.42978e-18\n", + "Time elapsed = 60.510 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 2.66e-15 | DW = 5.92708e-18\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 60.677 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 0.00e+00 | DW = 9.28475e-19\n", - "\n", - "Root = 0 = -6.995818305899173 = 6.000\n", - "Root = 1 = -6.570597289543093 = 6.000\n", - "Root = 2 = -6.570597289542542 = 6.000\n", - "Root = 3 = -6.570597289541823 = 6.000\n", - "Root = 4 = -6.277313551397241 = 6.000\n", - "Root = 5 = -6.225634144677118 = 8.000\n", - "Root = 6 = -6.112253573866418 = 6.000\n", - "Root = 7 = -6.112253573864956 = 6.000\n", - "Root = 8 = -6.112253573862747 = 6.000\n", - "Root = 9 = -6.032090249939520 = 4.000\n" + "Time elapsed = 62.807 | E[ 10] = -6.9958183059 -6.5705972895 -6.5705972895 -6.5705972895 -6.2773135514 -6.2256341447 -6.1122535739 -6.1122535739 -6.1122535739 -6.0320902499 | DE = 6.22e-15 | DW = 8.68828e-19\n", + "\n", + "Root = 0 = -6.995818305899857 = 6.000\n", + "Root = 1 = -6.570597289542269 = 6.000\n", + "Root = 2 = -6.570597289541987 = 6.000\n", + "Root = 3 = -6.570597289541616 = 6.000\n", + "Root = 4 = -6.277313551396532 = 6.000\n", + "Root = 5 = -6.225634144674588 = 8.000\n", + "Root = 6 = -6.112253573866735 = 6.000\n", + "Root = 7 = -6.112253573864114 = 6.000\n", + "Root = 8 = -6.112253573862018 = 6.000\n", + "Root = 9 = -6.032090249937025 = 4.000\n" ] } ], @@ -508,7 +508,7 @@ "base_uri": "https://localhost:8080/" }, "id": "XdwaoNOjXINz", - "outputId": "c6a8f9af-10a5-48bc-8fa3-862fcefc2aba" + "outputId": "1eb80dd7-03fa-4026-cdc5-f89c9ed2a690" }, "outputs": [ { @@ -517,33 +517,33 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 1.026 | E = -18.5867775673 | DW = 4.33791e-12\n", + "Time elapsed = 1.352 | E = -18.5868471274 | DW = 4.25342e-12\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 3.090 | E = -18.5873694219 | DE = -5.92e-04 | DW = 3.77544e-16\n", + "Time elapsed = 3.270 | E = -18.5873694219 | DE = -5.22e-04 | DW = 2.76148e-16\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 3.436 | E = -18.5873694219 | DE = -7.11e-15 | DW = 3.97569e-17\n", + "Time elapsed = 3.638 | E = -18.5873694219 | DE = 1.42e-14 | DW = 3.15333e-17\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 3.813 | E = -18.5873694219 | DE = -8.30e-12 | DW = 1.83165e-17\n", + "Time elapsed = 3.883 | E = -18.5873694219 | DE = -7.11e-15 | DW = 1.73802e-17\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 4.397 | E = -18.5873694219 | DE = 3.55e-15 | DW = 1.35857e-19\n", + "Time elapsed = 4.136 | E = -18.5873694219 | DE = -1.07e-14 | DW = 1.72020e-19\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 4.703 | E = -18.5873694219 | DE = -3.55e-15 | DW = 1.43599e-19\n", + "Time elapsed = 4.379 | E = -18.5873694219 | DE = -3.55e-15 | DW = 1.76578e-19\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 4.971 | E = -18.5873694219 | DE = -1.07e-14 | DW = 8.50577e-20\n", + "Time elapsed = 4.638 | E = -18.5873694219 | DE = 1.42e-14 | DW = 1.42126e-19\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 5.226 | E = -18.5873694219 | DE = 3.55e-15 | DW = 1.44991e-19\n", + "Time elapsed = 4.889 | E = -18.5873694219 | DE = 7.11e-15 | DW = 1.64026e-19\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 5.415 | E = -18.5873694219 | DE = 0.00e+00 | DW = 8.57382e-20\n", + "Time elapsed = 5.082 | E = -18.5873694219 | DE = 0.00e+00 | DW = 4.36925e-20\n", "\n", - "DMRG energy = -18.587369421896540 (per site = -1.858737)\n" + "DMRG energy = -18.587369421888660 (per site = -1.858737)\n" ] } ], @@ -613,7 +613,7 @@ "base_uri": "https://localhost:8080/" }, "id": "QlYXVVljUKVU", - "outputId": "7eff7afe-02e6-4e47-e11c-fb6c2f376ef2" + "outputId": "ab73ead6-bb4e-44d3-f694-0fdbbac638f0" }, "outputs": [ { @@ -622,33 +622,33 @@ "text": [ "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 11.778 | E = -0.5120663491 | DW = 1.30017e-05\n", + "Time elapsed = 11.895 | E = -0.5120719523 | DW = 1.23872e-05\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 18.660 | E = -0.5145229771 | DE = -2.46e-03 | DW = 4.16418e-08\n", + "Time elapsed = 18.957 | E = -0.5145229870 | DE = -2.45e-03 | DW = 4.15733e-08\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 23.883 | E = -0.5145506979 | DE = -2.77e-05 | DW = 3.51827e-07\n", + "Time elapsed = 23.887 | E = -0.5145506994 | DE = -2.77e-05 | DW = 3.52213e-07\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 26.629 | E = -0.5145508464 | DE = -1.48e-07 | DW = 4.79795e-07\n", + "Time elapsed = 27.112 | E = -0.5145508474 | DE = -1.48e-07 | DW = 4.79478e-07\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 34.588 | E = -0.5145512453 | DE = -3.99e-07 | DW = 4.81635e-09\n", + "Time elapsed = 35.962 | E = -0.5145512416 | DE = -3.94e-07 | DW = 4.92086e-09\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 47.894 | E = -0.5145512513 | DE = -6.07e-09 | DW = 4.36734e-09\n", + "Time elapsed = 51.138 | E = -0.5145512481 | DE = -6.52e-09 | DW = 1.13909e-08\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 61.178 | E = -0.5145512510 | DE = 2.96e-10 | DW = 1.36107e-09\n", + "Time elapsed = 66.481 | E = -0.5145512509 | DE = -2.71e-09 | DW = 5.72487e-09\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 74.667 | E = -0.5145512506 | DE = 4.30e-10 | DW = 8.13159e-10\n", + "Time elapsed = 81.167 | E = -0.5145512504 | DE = 4.79e-10 | DW = 1.74450e-09\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 84.889 | E = -0.5145512503 | DE = 2.84e-10 | DW = 9.28021e-19\n", + "Time elapsed = 92.574 | E = -0.5145512501 | DE = 3.14e-10 | DW = 2.19490e-18\n", "\n", - "DMRG energy (per site) = -0.514551250318804\n" + "DMRG energy (per site) = -0.514551250064920\n" ] } ], @@ -764,7 +764,7 @@ "base_uri": "https://localhost:8080/" }, "id": "bH-6fp6dGij1", - "outputId": "53f493a3-7493-4f21-e65f-cbc131851f78" + "outputId": "a6444d65-75b0-4f9e-a8d8-7532632ef4c6" }, "outputs": [ { @@ -773,55 +773,55 @@ "text": [ "\n", "Build MPO | Nsites = 16 | Nterms = 96 | Algorithm = FastBIP | Cutoff = 1.00e-14\n", - " Site = 0 / 16 .. Mmpo = 5 DW = 0.00e+00 NNZ = 5 SPT = 0.0000 Tmvc = 0.000 T = 0.032\n", - " Site = 1 / 16 .. Mmpo = 10 DW = 0.00e+00 NNZ = 13 SPT = 0.7400 Tmvc = 0.000 T = 0.021\n", - " Site = 2 / 16 .. Mmpo = 14 DW = 0.00e+00 NNZ = 18 SPT = 0.8714 Tmvc = 0.000 T = 0.041\n", - " Site = 3 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9127 Tmvc = 0.000 T = 0.012\n", - " Site = 4 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9321 Tmvc = 0.000 T = 0.009\n", - " Site = 5 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.012\n", - " Site = 6 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.011\n", - " Site = 7 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.012\n", - " Site = 8 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9321 Tmvc = 0.000 T = 0.015\n", - " Site = 9 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.013\n", - " Site = 10 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.013\n", - " Site = 11 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.012\n", - " Site = 12 / 16 .. Mmpo = 14 DW = 0.00e+00 NNZ = 22 SPT = 0.9127 Tmvc = 0.000 T = 0.021\n", - " Site = 13 / 16 .. Mmpo = 10 DW = 0.00e+00 NNZ = 18 SPT = 0.8714 Tmvc = 0.000 T = 0.018\n", - " Site = 14 / 16 .. Mmpo = 5 DW = 0.00e+00 NNZ = 13 SPT = 0.7400 Tmvc = 0.000 T = 0.011\n", - " Site = 15 / 16 .. Mmpo = 1 DW = 0.00e+00 NNZ = 5 SPT = 0.0000 Tmvc = 0.000 T = 0.008\n", - "Ttotal = 0.263 Tmvc-total = 0.001 MPO bond dimension = 18 MaxDW = 0.00e+00\n", + " Site = 0 / 16 .. Mmpo = 5 DW = 0.00e+00 NNZ = 5 SPT = 0.0000 Tmvc = 0.000 T = 0.005\n", + " Site = 1 / 16 .. Mmpo = 10 DW = 0.00e+00 NNZ = 13 SPT = 0.7400 Tmvc = 0.000 T = 0.008\n", + " Site = 2 / 16 .. Mmpo = 14 DW = 0.00e+00 NNZ = 18 SPT = 0.8714 Tmvc = 0.000 T = 0.003\n", + " Site = 3 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9127 Tmvc = 0.000 T = 0.003\n", + " Site = 4 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9321 Tmvc = 0.000 T = 0.003\n", + " Site = 5 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.003\n", + " Site = 6 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.003\n", + " Site = 7 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.004\n", + " Site = 8 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 22 SPT = 0.9321 Tmvc = 0.000 T = 0.003\n", + " Site = 9 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.003\n", + " Site = 10 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.005\n", + " Site = 11 / 16 .. Mmpo = 18 DW = 0.00e+00 NNZ = 26 SPT = 0.9198 Tmvc = 0.000 T = 0.004\n", + " Site = 12 / 16 .. Mmpo = 14 DW = 0.00e+00 NNZ = 22 SPT = 0.9127 Tmvc = 0.000 T = 0.004\n", + " Site = 13 / 16 .. Mmpo = 10 DW = 0.00e+00 NNZ = 18 SPT = 0.8714 Tmvc = 0.000 T = 0.006\n", + " Site = 14 / 16 .. Mmpo = 5 DW = 0.00e+00 NNZ = 13 SPT = 0.7400 Tmvc = 0.000 T = 0.003\n", + " Site = 15 / 16 .. Mmpo = 1 DW = 0.00e+00 NNZ = 5 SPT = 0.0000 Tmvc = 0.000 T = 0.003\n", + "Ttotal = 0.065 Tmvc-total = 0.001 MPO bond dimension = 18 MaxDW = 0.00e+00\n", "NNZ = 316 SIZE = 3486 SPT = 0.9094\n", "\n", - "Rank = 0 Ttotal = 0.480 MPO method = FastBipartite bond dimension = 18 NNZ = 316 SIZE = 3486 SPT = 0.9094\n", + "Rank = 0 Ttotal = 0.120 MPO method = FastBipartite bond dimension = 18 NNZ = 316 SIZE = 3486 SPT = 0.9094\n", "\n", "Sweep = 0 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 3.850 | E = -8.9796008520 | DW = 5.86154e-07\n", + "Time elapsed = 2.027 | E = -8.9766173567 | DW = 5.77272e-07\n", "\n", "Sweep = 1 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 7.778 | E = -9.0284250184 | DE = -4.88e-02 | DW = 1.36125e-06\n", + "Time elapsed = 5.533 | E = -9.0283170174 | DE = -5.17e-02 | DW = 1.35935e-06\n", "\n", "Sweep = 2 | Direction = forward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 9.742 | E = -9.0298619274 | DE = -1.44e-03 | DW = 1.23409e-06\n", + "Time elapsed = 7.572 | E = -9.0298617564 | DE = -1.54e-03 | DW = 1.23213e-06\n", "\n", "Sweep = 3 | Direction = backward | Bond dimension = 250 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", - "Time elapsed = 10.604 | E = -9.0298670256 | DE = -5.10e-06 | DW = 1.13415e-06\n", + "Time elapsed = 8.459 | E = -9.0298668762 | DE = -5.12e-06 | DW = 1.13216e-06\n", "\n", "Sweep = 4 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 11.898 | E = -9.0298686867 | DE = -1.66e-06 | DW = 2.27179e-10\n", + "Time elapsed = 9.808 | E = -9.0298686868 | DE = -1.81e-06 | DW = 2.27239e-10\n", "\n", "Sweep = 5 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 12.869 | E = -9.0298686872 | DE = -4.35e-10 | DW = 1.12668e-10\n", + "Time elapsed = 10.799 | E = -9.0298686872 | DE = -4.29e-10 | DW = 1.12672e-10\n", "\n", "Sweep = 6 | Direction = forward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 13.782 | E = -9.0298686872 | DE = -8.19e-12 | DW = 2.27110e-10\n", + "Time elapsed = 11.850 | E = -9.0298686872 | DE = -6.54e-12 | DW = 2.27115e-10\n", "\n", "Sweep = 7 | Direction = backward | Bond dimension = 500 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", - "Time elapsed = 14.710 | E = -9.0298686872 | DE = -1.02e-11 | DW = 1.12643e-10\n", + "Time elapsed = 12.894 | E = -9.0298686872 | DE = -8.10e-12 | DW = 1.12646e-10\n", "\n", "Sweep = 8 | Direction = forward | Bond dimension = 500 | Noise = 0.00e+00 | Dav threshold = 1.00e-09\n", - "Time elapsed = 15.473 | E = -9.0298686872 | DE = 2.91e-11 | DW = 1.78156e-19\n", + "Time elapsed = 13.429 | E = -9.0298686872 | DE = 2.92e-11 | DW = 1.97857e-19\n", "\n", - "DMRG energy = -9.029868687160421 (per site = -0.564367)\n" + "DMRG energy = -9.029868687164758 (per site = -0.564367)\n" ] } ], @@ -878,6 +878,210 @@ " noises=[1e-4] * 4 + [1e-5] * 4 + [0], thrds=[1e-10] * 8, dav_max_iter=30, iprint=1)\n", "print(\"DMRG energy = %20.15f (per site = %10.6f)\" % (energy, energy / L))" ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CQh7mYEgdZBf" + }, + "source": [ + "## Spatial Reflection Symmetry\n", + "\n", + "As a more advanced example, in the following we solve the Heisenberg model\n", + "$$\n", + "\\hat{H} = \\sum_{i=1}^{L-1} \\Big( \\frac{1}{2} S^+_{i} S^-_{i+1} + \\frac{1}{2} S^-_{i} S^+_{i+1} + S^z_{i} S^z_{i+1} \\Big)\n", + "$$\n", + "using $U(1) \\times Z_2$ (projected spin $\\hat{S}_z$ and spatial reflection $\\hat{R}$ about the center of the chain) symmetry.\n", + "\n", + "First, we need to transform the local states so that they have well defined quantum numbers in the $U(1) \\times Z_2$ symmetry group. Consider a two-site system. The states can be represented as $|\\alpha\\alpha\\rangle,|\\alpha\\beta\\rangle,|\\beta\\alpha\\rangle$, and $|\\beta\\beta\\rangle$. Since $\\hat{R}|\\alpha\\beta\\rangle=|\\beta\\alpha\\rangle$, states $|\\alpha\\beta\\rangle$ and $|\\beta\\alpha\\rangle$ do not have well-defined quantum number for $\\hat{R}$. Therefore, we define the following four local states for the two-site system:\n", + "\n", + "$$\n", + "|0\\rangle = |\\alpha\\alpha\\rangle,\\quad\n", + "|1\\rangle = \\big(|\\alpha\\beta\\rangle + |\\beta\\alpha\\rangle \\big) / \\sqrt{2},\\quad\n", + "|2\\rangle = \\big(|\\alpha\\beta\\rangle - |\\beta\\alpha\\rangle \\big) / \\sqrt{2},\\quad\n", + "|3\\rangle = |\\beta\\beta\\rangle.\n", + "$$\n", + "which are four eigenstates of the $\\hat{R}$ operator with eigenvalues $+1, +1, -1, +1$. In $Z_2$ notation, the quantum number will be 0 (even, $R = +1$) or 1 (odd, $R = -1$).\n", + "\n", + "For a $L$-site system, the above local states will mix states in site 0 and $L - 1$, and in site 1 and $L - 2$, etc. Therefore, we reorder the sites according to (using $L = 8$ as an example):\n", + "\n", + "$$\n", + "01234567 \\quad\\rightarrow\\quad (07)(16)(25)(34)\n", + "$$\n", + "\n", + "and merge the two sites in each parenthesis into one big site.\n", + "\n", + "Second, we need to transform the local operators so that they have well defined quantum numbers in the $U(1) \\times Z_2$ symmetry group. We first write each operator in the above $|0\\rangle, |1\\rangle, |2\\rangle, |3\\rangle$ basis. Since now each big site has four states, we have two $\\hat{S}^+$ operators denoted as $\\hat{S}^+_L$ and $\\hat{S}^+_R$, acting on the site from the left-half-chain and the right-half-chain, respectively (for example, when $L=8$, in the first big site, $\\hat{S}^+_L = \\hat{S}^+_0$ and $\\hat{S}^+_R = \\hat{S}^+_7$). We have\n", + "\n", + "$$\n", + "\\hat{S}_L^+ = \\frac{1}{\\sqrt{2}}\\begin{pmatrix} 0 & 1 & -1 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 0 & 0 \\\\\\end{pmatrix}\n", + "$$\n", + "\n", + "As $\\hat{S}_L^+$ do not commute or anticommute with $\\hat{R} = \\mathrm{diag}(1, 1, -1, 1)$, we split it into the odd and even parts:\n", + "$$\n", + "\\hat{S}^+_{L,\\mathrm{odd}} = \\frac{1}{\\sqrt{2}}\\begin{pmatrix} 0 & 0 & -1 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 0 & 0 \\\\\\end{pmatrix},\\quad\n", + "\\hat{S}^+_{L,\\mathrm{even}} = \\frac{1}{\\sqrt{2}}\\begin{pmatrix} 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\\\end{pmatrix}\n", + "$$\n", + "\n", + "such that $[\\hat{S}^+_{L,\\mathrm{odd}}, \\hat{R}]_+ = 0$ and $[\\hat{S}^+_{L,\\mathrm{even}}, \\hat{R}]_- = 0$.\n", + "\n", + "The other operators can be symmetry-adapted in a similar way.\n", + "\n", + "Finally, for the Hamiltonian we require $[\\hat{H}, \\hat{R}]_- = 0$. So terms like $S^+_{i}S^-_{i+1}$ will be rewritten as\n", + "\n", + "$$\n", + "S^+_{i,\\mathrm{odd}}S^-_{i+1,\\mathrm{odd}} + S^+_{i,\\mathrm{even}}S^-_{i+1,\\mathrm{even}}.\n", + "$$\n", + "\n", + "The following script will compute the $R = +1$ (spatial reflection even) state and the $R = -1$ (spatial reflection odd) state (both with $S_z=0$) for $L = 16$ Heisenberg model. The two states correspond to the ground state and the first excited state of the model when computed using only $U(1)$ symmetry, respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "EcxGm7LynmmI", + "outputId": "fcaaff56-c0cb-4224-aee0-763eb7bc9a2a" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Sweep = 0 | Direction = forward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.603 | E = -6.9117371456 | DW = 4.53183e-09\n", + "\n", + "Sweep = 1 | Direction = backward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.774 | E = -6.9117371456 | DE = -1.86e-11 | DW = 4.11573e-09\n", + "\n", + "Sweep = 2 | Direction = forward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.923 | E = -6.9117371456 | DE = -2.58e-13 | DW = 4.52743e-09\n", + "\n", + "Sweep = 3 | Direction = backward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.035 | E = -6.9117371456 | DE = 3.38e-14 | DW = 4.11606e-09\n", + "\n", + "Sweep = 4 | Direction = forward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.197 | E = -6.9117371456 | DE = -4.62e-14 | DW = 8.44772e-14\n", + "\n", + "Sweep = 5 | Direction = backward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.339 | E = -6.9117371456 | DE = 7.43e-13 | DW = 4.30855e-15\n", + "\n", + "Sweep = 6 | Direction = forward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.495 | E = -6.9117371456 | DE = 7.11e-15 | DW = 2.47224e-15\n", + "\n", + "Sweep = 7 | Direction = backward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.666 | E = -6.9117371456 | DE = -1.78e-15 | DW = 3.80529e-15\n", + "\n", + "Sweep = 8 | Direction = forward | Bond dimension = 200 | Noise = 0.00e+00 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.781 | E = -6.9117371456 | DE = 9.77e-15 | DW = 1.63719e-19\n", + "\n", + "\n", + "Sweep = 0 | Direction = forward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.343 | E = -6.6924604290 | DW = 3.17982e-09\n", + "\n", + "Sweep = 1 | Direction = backward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.453 | E = -6.6924604290 | DE = -2.57e-11 | DW = 1.81122e-09\n", + "\n", + "Sweep = 2 | Direction = forward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.548 | E = -6.6924604290 | DE = 1.47e-11 | DW = 3.16752e-09\n", + "\n", + "Sweep = 3 | Direction = backward | Bond dimension = 100 | Noise = 1.00e-04 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.637 | E = -6.6924604290 | DE = -1.61e-11 | DW = 1.81055e-09\n", + "\n", + "Sweep = 4 | Direction = forward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.778 | E = -6.6924604290 | DE = 1.59e-11 | DW = 4.93387e-14\n", + "\n", + "Sweep = 5 | Direction = backward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 0.922 | E = -6.6924604290 | DE = 1.31e-13 | DW = 2.59123e-14\n", + "\n", + "Sweep = 6 | Direction = forward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.072 | E = -6.6924604290 | DE = 4.80e-14 | DW = 3.07917e-14\n", + "\n", + "Sweep = 7 | Direction = backward | Bond dimension = 200 | Noise = 1.00e-05 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.247 | E = -6.6924604290 | DE = 3.38e-14 | DW = 1.31860e-14\n", + "\n", + "Sweep = 8 | Direction = forward | Bond dimension = 200 | Noise = 0.00e+00 | Dav threshold = 1.00e-10\n", + "Time elapsed = 1.367 | E = -6.6924604290 | DE = 4.00e-14 | DW = 5.48050e-20\n", + "\n", + "R = even : DMRG energy = -6.911737145570076\n", + "R = odd : DMRG energy = -6.692460429006416\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from pyblock2.driver.core import DMRGDriver, SymmetryTypes\n", + "\n", + "L = 16\n", + "\n", + "bond_dims = [100] * 4 + [200] * 6\n", + "noises = [1e-4] * 4 + [1e-5] * 4 + [0]\n", + "thrds = [1e-10] * 10\n", + "\n", + "driver = DMRGDriver(scratch=\"./tmp\", symm_type=SymmetryTypes.SAny, n_threads=4)\n", + "\n", + "X = (L + 1) // 2\n", + "\n", + "# U1: spin, Z2: spatial reflection\n", + "driver.set_symmetry_groups('U1', 'Z2')\n", + "Q = driver.bw.SX\n", + "\n", + "site_basis, site_ops = [], []\n", + "for k in range(X):\n", + " if L % 2 == 0 or k < L // 2:\n", + " site_basis.append([(Q(-2, 0), 1), (Q(0, 0), 1), (Q(0, 1), 1), (Q(2, 0), 1)]) # [0+-2]\n", + " ops = {\n", + " \"\": np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]), # identity\n", + " \"L\": np.array([[0, 0, -1, 0], [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0]]) / (2**0.5), # S+ left odd\n", + " \"l\": np.array([[0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]]) / (2**0.5), # S+ left even\n", + " \"R\": np.array([[0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, -1], [0, 0, 0, 0]]) / (2**0.5), # S+ right odd\n", + " \"r\": np.array([[0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]]) / (2**0.5), # S+ right even\n", + " \"S\": np.array([[0, 0, 0, 0], [0, 0, 0, 0], [-1, 0, 0, 0], [0, 0, 1, 0]]) / (2**0.5), # S- left odd\n", + " \"s\": np.array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0]]) / (2**0.5), # S- left even\n", + " \"T\": np.array([[0, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 0], [0, 0, -1, 0]]) / (2**0.5), # S- right odd\n", + " \"t\": np.array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0]]) / (2**0.5), # S- right even\n", + " \"V\": np.array([[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]) * 0.5, # Sz left odd\n", + " \"v\": np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, -1]]) * 0.5, # Sz left even\n", + " \"W\": np.array([[0, 0, 0, 0], [0, 0, -1, 0], [0, -1, 0, 0], [0, 0, 0, 0]]) * 0.5, # Sz right odd\n", + " \"w\": np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, -1]]) * 0.5, # Sz right even\n", + " }\n", + " else:\n", + " site_basis.append([(Q(-1, 0), 1), (Q(1, 0), 1)]) # [01/ab]\n", + " ops = {\n", + " \"\": np.array([[1, 0], [0, 1]]), # identity\n", + " \"l\": np.array([[0, 1], [0, 0]]), # S+\n", + " \"s\": np.array([[0, 0], [1, 0]]), # S-\n", + " \"v\": np.array([[0.5, 0], [0, -0.5]]) # Sz\n", + " }\n", + " site_ops.append(ops)\n", + "\n", + "driver.initialize_system(n_sites=X, vacuum=Q(0, 0), target=Q(L % 2, 0), hamil_init=False)\n", + "driver.ghamil = driver.get_custom_hamiltonian(site_basis, site_ops)\n", + "\n", + "b = driver.expr_builder()\n", + "for i in range(L - 1):\n", + " term = (i == L // 2 or i + 1 == L // 2) and L % 2 == 1\n", + " for p, m in [(p, m) for p, m in [[\"LR\", \"ST\"], [\"lr\", \"st\"]][term:]]:\n", + " b.add_term(p[i >= X] + m[i + 1 >= X], [[i, L - 1 - i][i >= X], [i + 1, L - 2 - i][i + 1 >= X]], 0.5)\n", + " for m, p in [(m, p) for m, p in [[\"ST\", \"LR\"], [\"st\", \"lr\"]][term:]]:\n", + " b.add_term(m[i >= X] + p[i + 1 >= X], [[i, L - 1 - i][i >= X], [i + 1, L - 2 - i][i + 1 >= X]], 0.5)\n", + " for z, w in [(z, w) for z, w in [[\"VW\", \"VW\"], [\"vw\", \"vw\"]][term:]]:\n", + " b.add_term(z[i >= X] + w[i + 1 >= X], [[i, L - 1 - i][i >= X], [i + 1, L - 2 - i][i + 1 >= X]], 1.0)\n", + "\n", + "mpo = driver.get_mpo(b.finalize(fermionic_ops=\"\"), iprint=0)\n", + "\n", + "energies = [0.0] * 2\n", + "for r in [0, 1]:\n", + " ket = driver.get_random_mps(tag=\"KET\", bond_dim=100, target=Q(L % 2, r), nroots=1)\n", + " energies[r] = driver.dmrg(mpo, ket, n_sweeps=len(bond_dims), bond_dims=bond_dims, noises=noises, thrds=thrds, iprint=1)\n", + "\n", + "print('R = even : DMRG energy = %20.15f' % energies[0])\n", + "print('R = odd : DMRG energy = %20.15f' % energies[1])" + ] } ], "metadata": { diff --git a/docs/source/tutorial/hubbard.ipynb b/docs/source/tutorial/hubbard.ipynb index dc937834..f0d11719 100644 --- a/docs/source/tutorial/hubbard.ipynb +++ b/docs/source/tutorial/hubbard.ipynb @@ -130,7 +130,7 @@ "\n", "For example, ``b.add_term(\"dCc\", [1, 3, 0], 0.7)`` will add the term: $0.7 \\ a_{1\\alpha} a^\\dagger_{3\\beta} a^\\dagger_{0\\alpha}$.\n", "\n", - "Most of the time, there can be multiple terms differ only in the operator indices and coefficients. For this case, One can invoke ``add_term`` only once. So ``b.add_term(\"CD\", [1, 3, 3, 1, 2, 2, 2, 4], [0.7, 0.6, 0.5, 0.4])``\n", + "Most of the time, there can be multiple terms differ only in the operator indices and coefficients. For this case, one can invoke ``add_term`` only once. So ``b.add_term(\"CD\", [1, 3, 3, 1, 2, 2, 2, 4], [0.7, 0.6, 0.5, 0.4])``\n", "\n", "is equivalent to\n", "\n", @@ -217,7 +217,7 @@ "- ``bond_dim`` is the bond dimension of the initial guess MPS. The final optimized MPS may have a larger bond dimension.\n", "- ``nroots`` is the number of roots. If ``nroots > 1``, it will compute the ground state and ``nroots - 1`` low-energy excited states.\n", "\n", - "The DMRG algorithm consists of many \"sweeps\". The bond dimension of the MPS can increase after several sweeps. After a few tens of the sweeps, the MPS gradually converges to the ground state if ``nroots == 1``. To prevent stuck in local minima, we may add noise in most sweeps, but the last sweep will not have any noise (namely, ``noises[-1] == 0``) so that the accuracy of the final printed energy is not affected. In each sweep, the DMRG algorithm will optimize $L$ tensors in the MPS, one by one. For optimizing each tensor, an effective Hamiltonian will be created and the Davidson algorithm is used to sovle the eigenvalue problem of this effective Hamiltonian. The eigenvalue (energy) of this effective Hamiltonian is the same as the eigenvalue of the full many-body Hamiltonian (if the bond dimension of the MPS is big enough).\n", + "The DMRG algorithm consists of many \"sweeps\". The bond dimension of the MPS can increase after several sweeps. After a few tens of the sweeps, the MPS gradually converges to the ground state if ``nroots == 1``. To prevent from getting stuck in local minima, we may add noise in most sweeps, but the last sweep will not have any noise (namely, ``noises[-1] == 0``) so that the accuracy of the final printed energy is not affected. In each sweep, the DMRG algorithm will optimize $L$ tensors in the MPS, one by one. For optimizing each tensor, an effective Hamiltonian will be created and the Davidson algorithm is used to solve the eigenvalue problem of this effective Hamiltonian. The eigenvalue (energy) of this effective Hamiltonian is the same as the eigenvalue of the full many-body Hamiltonian (if the bond dimension of the MPS is big enough).\n", "\n", "Therefore, to run a DMRG calculation, we need to set up a \"sweep schedule\", namely, we need to set for each sweep: (a) the MPS bond dimension used in this sweep; (b) the noise used in this sweep; and (c) the Davidson algorithm convergence threshold for this sweep. Typically, these parameters should be changed every 4 to 5 sweeps (for Hubbard model with several hundred sites they may be changed every 30 to 50 sweeps), and the MPS bond dimension increases, while the noise and Davidson algorithm convergence decrease. The Davidson algorithm convergence cannot be set to zero.\n", "\n", diff --git a/docs/source/tutorial/qc-hamiltonians.ipynb b/docs/source/tutorial/qc-hamiltonians.ipynb index a862f00b..14b7df76 100644 --- a/docs/source/tutorial/qc-hamiltonians.ipynb +++ b/docs/source/tutorial/qc-hamiltonians.ipynb @@ -2107,7 +2107,11 @@ "\n", "We can also transform the spin-adapted MPS generated in the ``SU2`` mode to the non-spin-adapted MPS, which can be used in the ``SZ`` mode. After obtaining the non-spin-adapted MPS, one need to redo ``driver.initialize_system``, ``driver.get_qc_mpo``, etc. to make sure every object is now represented in the ``SZ`` mode, then you can operate on the ``SZ`` non-spin-adapted MPS.\n", "\n", - "In the following example, we first compute the spin-adapted MPS, then translate it into the non-spin-adapted MPS to extract the determinant coefficients." + "In the following example, we first compute the spin-adapted MPS, then translate it into the non-spin-adapted MPS to extract the determinant coefficients.\n", + "\n", + "As the transform from SU2 format to SZ format is only implemented for left canonicalized MPS, we need to add a line ``driver.align_mps_center(ket, ref=0)`` to change its canonical center to zero (if it is not zero) before translating an MPS from SU2 format to SZ format.\n", + "\n", + "For a non-singlet SU2 MPS (not the case in the example below), as it can have multiple SZ components, we need to specify a specific SZ component. This is done via the ``sz`` argument of ``driver.mps_change_to_sz``. When we extract only a component of the non-singlet SU2 MPS, the norm of the extracted MPS will be smaller than the norm of the original SU2 MPS. Therefore, one may explicitly compute the ``norm**2`` of the translated MPS (using ``driver.expectation(zket, driver.get_identity_mpo(), zket)``), and the computed PDM quantities should be scaled by ``1 / norm**2``. Quantities like orbital entropies have to be computed after the MPS is normalized. MPSs can be normalized using ``zket.iscale(1 / norm)``." ] }, { @@ -2202,6 +2206,7 @@ " thrds=thrds, iprint=1)\n", "print('DMRG energy = %20.15f' % energy)\n", "\n", + "driver.align_mps_center(ket, ref=0)\n", "csfs, coeffs = driver.get_csf_coefficients(ket, cutoff=0.05, iprint=1)\n", "zket = driver.mps_change_to_sz(ket, \"ZKET\")\n", "\n", diff --git a/docs/source/user/advanced.rst b/docs/source/user/advanced.rst index 280b41bf..de69cc9e 100644 --- a/docs/source/user/advanced.rst +++ b/docs/source/user/advanced.rst @@ -104,6 +104,7 @@ The following input file is used for this step: :: spin 0 irrep 1 + hf_occ integral schedule 0 1000 0 0 end diff --git a/docs/source/user/installation.rst b/docs/source/user/installation.rst index 0f4c662f..c22ad5e8 100644 --- a/docs/source/user/installation.rst +++ b/docs/source/user/installation.rst @@ -15,15 +15,15 @@ One can install ``block2`` using ``pip``: pip install block2 -* Hybrid openMP/MPI version (requiring openMPI 4.1.x) :: +* Hybrid openMP/MPI version (requiring openMPI 5.0.x for ``block2-mpi >= 0.5.3`` or 4.1.x for ``block2-mpi <= 0.5.2`` and ``block2-mpi <= 0.5.3rc19``) :: pip install block2-mpi -* Binary format are prepared via ``pip`` for python 3.7, 3.8, 3.9, 3.10, and 3.11 with macOS (x86 and arm64, no-MPI) or Linux (no-MPI/openMPI). +* Binary format are prepared via ``pip`` for python 3.8, 3.9, 3.10, 3.11, 3.12, and 3.13 with macOS (x86 and arm64, no-MPI), Linux (no-MPI/openMPI), or Windows (x86, no-MPI). If these binaries have some problems, you can use the ``--no-binary`` option of ``pip`` to force building from source (for example, ``pip install block2 --no-binary block2``). -* For very new Python versions (3.12) and Windows, the ``--extra-index-url`` option of ``pip`` is required, see below for installing the developement version of ``block2``. +* For very new Python versions, the ``--extra-index-url`` option of ``pip`` is required, see below for installing the developement version of ``block2``. * One should only install one of ``block2`` and ``block2-mpi``. ``block2-mpi`` covers all features in ``block2``, but its dependence on mpi library can sometimes be difficult to deal with. @@ -35,7 +35,7 @@ One can install ``block2`` using ``pip``: pip install block2== --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/ pip install block2-mpi== --extra-index-url=https://block-hczhai.github.io/block2-preview/pypi/ - where ```` can be some development version number like ``0.5.2rc17`` (see https://github.com/block-hczhai/block2-preview/tags for a complete list of version numbers. The letter ``p`` is not needed). + where ```` can be some development version number like ``0.5.3rc20`` (see https://github.com/block-hczhai/block2-preview/tags for a complete list of version numbers. The letter ``p`` is not needed). To force reinstalling an updated version, you may consider ``pip`` options ``--upgrade --force-reinstall --no-deps --no-cache-dir``. Manual Installation diff --git a/pyblock2/_pyscf/mcscf/__init__.py b/pyblock2/_pyscf/mcscf/__init__.py index 52312f22..337f8570 100644 --- a/pyblock2/_pyscf/mcscf/__init__.py +++ b/pyblock2/_pyscf/mcscf/__init__.py @@ -1 +1 @@ -from .uno import get_uno, select_active_space, sort_orbitals \ No newline at end of file +from .uno import get_uno, select_active_space, sort_orbitals, pmloc \ No newline at end of file diff --git a/pyblock2/_pyscf/mcscf/uno.py b/pyblock2/_pyscf/mcscf/uno.py index 579a0bd6..6c8adc3d 100644 --- a/pyblock2/_pyscf/mcscf/uno.py +++ b/pyblock2/_pyscf/mcscf/uno.py @@ -23,6 +23,8 @@ https://github.com/pyscf/dmrgscf/blob/master/examples/32-dmrg_casscf_nevpt2_for_FeS.py Author: Zhendong Li Qiming Sun + Revised pmloc for mol as partition list: + Huanchen Zhai, Oct 5, 2024 """ import numpy as np @@ -39,22 +41,26 @@ def lowdin(s): return np.dot(v / np.sqrt(e), v.T.conj()) -def loc(mol, mocoeff, tol=1e-6, maxcycle=1000, iop=0, iprint=1): - part = {} - for iatom in range(mol.natm): - part[iatom] = [] - ncgto = 0 - for binfo in mol._bas: - atom_id = binfo[0] - lang = binfo[1] - ncntr = binfo[3] - nbas = ncntr * (2 * lang + 1) - part[atom_id] += range(ncgto, ncgto + nbas) - ncgto += nbas - partition = [] - for iatom in range(mol.natm): - partition.append(part[iatom]) - ova = mol.intor_symmetric("cint1e_ovlp_sph") +def pmloc(mol, mocoeff, tol=1e-6, maxcycle=1000, iop=0, iprint=1): + if not isinstance(mol, list): + part = {} + for iatom in range(mol.natm): + part[iatom] = [] + ncgto = 0 + for binfo in mol._bas: + atom_id = binfo[0] + lang = binfo[1] + ncntr = binfo[3] + nbas = ncntr * (2 * lang + 1) + part[atom_id] += range(ncgto, ncgto + nbas) + ncgto += nbas + partition = [] + for iatom in range(mol.natm): + partition.append(part[iatom]) + ova = mol.intor_symmetric("cint1e_ovlp_sph") + else: + ova, partition = None, mol + assert iop == 1 if iprint: print() print("[pm_loc_kernel]") @@ -62,16 +68,24 @@ def loc(mol, mocoeff, tol=1e-6, maxcycle=1000, iop=0, iprint=1): print(" tol=", tol) print(" maxcycle=", maxcycle) print(" partition=", len(partition), "\\n", partition) - k = mocoeff.shape[0] n = mocoeff.shape[1] natom = len(partition) - def genPaij(mol, mocoeff, ova, partition, iop): + def gen_paij_part(mocoeff, partition): + s12c = mocoeff.copy() + # Lowdin + pija = np.zeros((natom, n, n)) + for iatom in range(natom): + idx = partition[iatom] + pija[iatom] = np.dot(s12c[idx, :].T, s12c[idx, :]) + pija = pija.transpose(1, 2, 0).copy() + return pija + + def gen_paij(mol, mocoeff, ova, partition, iop): c = mocoeff.copy() # Mulliken matrix if iop == 0: cts = c.T.dot(ova) - natom = len(partition) pija = np.zeros((natom, n, n)) for iatom in range(natom): idx = partition[iatom] @@ -81,7 +95,6 @@ def genPaij(mol, mocoeff, ova, partition, iop): elif iop == 1: s12 = sqrtm(ova) s12c = s12.T.dot(c) - natom = len(partition) pija = np.zeros((natom, n, n)) for iatom in range(natom): idx = partition[iatom] @@ -97,7 +110,10 @@ def genPaij(mol, mocoeff, ova, partition, iop): return pija u = np.identity(n) - pija = genPaij(mol, mocoeff, ova, partition, iop) + if not isinstance(mol, list): + pija = gen_paij(mol, mocoeff, ova, partition, iop) + else: + pija = gen_paij_part(mocoeff, partition) # Start def funval(pija): @@ -294,8 +310,8 @@ def scdm(coeff, overlap, aux): clmo = c_orbs almo = a_orbs - uc = loc(mol, clmo, iprint=iprint)[1] - ua = loc(mol, almo, iprint=iprint)[1] + uc = pmloc(mol, clmo, iprint=iprint)[1] + ua = pmloc(mol, almo, iprint=iprint)[1] clmo = clmo.dot(uc) almo = almo.dot(ua) @@ -456,7 +472,7 @@ def psort(ova, fav, pT, coeff): actmo = coeff[:, np.array(cas_list, dtype=int)] if do_loc: - ua = loc(mol, actmo, iprint=iprint)[1] + ua = pmloc(mol, actmo, iprint=iprint)[1] actmo = actmo.dot(ua) actmo, actocc, acte = psort(ova, fav, pav, actmo) @@ -478,7 +494,7 @@ def psort(ova, fav, pT, coeff): if len(actmo[:, lidx]) != 0: if iprint: print("low orbs = ", np.array(list(range(len(lidx))))[lidx]) - ua = loc(mol, actmo[:, lidx], iprint=iprint)[1] + ua = pmloc(mol, actmo[:, lidx], iprint=iprint)[1] actmo[:, lidx] = actmo[:, lidx].dot(ua) actmo[:, lidx], actocc[lidx], acte[lidx] = psort( ova, fav, pav, actmo[:, lidx] @@ -487,7 +503,7 @@ def psort(ova, fav, pT, coeff): if len(actmo[:, midx]) != 0: if iprint: print("mid orbs = ", np.array(list(range(len(midx))))[midx]) - ua = loc(mol, actmo[:, midx], iprint=iprint)[1] + ua = pmloc(mol, actmo[:, midx], iprint=iprint)[1] actmo[:, midx] = actmo[:, midx].dot(ua) actmo[:, midx], actocc[midx], acte[midx] = psort( ova, fav, pav, actmo[:, midx] @@ -496,7 +512,7 @@ def psort(ova, fav, pT, coeff): if len(actmo[:, hidx]) != 0: if iprint: print("high orbs = ", np.array(list(range(len(hidx))))[hidx]) - ua = loc(mol, actmo[:, hidx], iprint=iprint)[1] + ua = pmloc(mol, actmo[:, hidx], iprint=iprint)[1] actmo[:, hidx] = actmo[:, hidx].dot(ua) actmo[:, hidx], actocc[hidx], acte[hidx] = psort( ova, fav, pav, actmo[:, hidx] diff --git a/pyblock2/driver/block2main b/pyblock2/driver/block2main index eebbe9aa..28b407fd 100755 --- a/pyblock2/driver/block2main +++ b/pyblock2/driver/block2main @@ -26,6 +26,14 @@ Author: Zhi-Hao Cui """ +import os +import sys + +if os.name == "nt" and sys.version_info[1] >= 8: + for path in os.environ["PATH"].split(";"): + if path != "" and os.path.exists(os.path.abspath(path)): + os.add_dll_directory(os.path.abspath(path)) + from block2 import SZ, SU2, SZK, SU2K, SGF, DoubleFPCodec as FPCodec from block2 import Global, OpNamesSet, NoiseTypes, DecompositionTypes, Threading, ThreadingTypes from block2 import init_memory, release_memory, set_mkl_num_threads, read_occ, TruncationTypes @@ -1431,7 +1439,7 @@ if "statespecific" in dic and "proj_weights" in dic: # prepare mps if len(mps_tags) > 1 or ("compression" in dic and "random_mps_init" not in dic) \ - or "stopt_sampling" in dic: + or "stopt_sampling" in dic or "delta_t" in dic: nroots = len(mps_tags) mps = None mps_info = None @@ -2599,7 +2607,7 @@ if not pre_run: '--', linewidth=1, color='#5FA8AB') plt.plot(ext_dws, ext_eners, 'o', color='#38686A', markerfacecolor='white', markersize=5) - plt.text(ddw / 12, emax, "$E(M=\\infty) = %.6f \pm %.6f \\mathrm{\\ Hartree}$" % + plt.text(ddw / 12, emax, "$E(M=\\infty) = %.6f \\pm %.6f \\mathrm{\\ Hartree}$" % (reg.intercept, abs(reg.intercept - emin) / 5), color='#38686A', fontsize=12) plt.text(ddw / 12, emax - de / 12, "$R^2 = %.6f$" % (reg.rvalue ** 2), color='#38686A', fontsize=12) @@ -4366,9 +4374,34 @@ if not pre_run: "A tag name must be given for the keyword copy_mps/restart_copy_mps!") if "trans_mps_to_sz" in dic: assert "nonspinadapted" not in dic - mps.info.load_mutable() - mps.load_mutable() - cp_mps = trans_mps(UnfusedMPS(mps), copy_tag, mpo.tf.opf.cg) + + if mps.center != 0: + xmps = mps.deep_copy(copy_tag + "@TMP") + _print('change canonical form ...') + cf = str(xmps.canonical_form) + ime = MovingEnvironment(impo, xmps, xmps, "IEX") + ime.delayed_contraction = OpNamesSet.normal_ops() + ime.cached_contraction = cached_contraction + ime.init_environments(False) + if not complex_mps: + expect = Expect(ime, xmps.info.bond_dim, xmps.info.bond_dim) + else: + expect = ComplexExpect(ime, xmps.info.bond_dim, xmps.info.bond_dim) + expect.iprint = max(min(outputlevel, 3), 0) + expect.solve(True, xmps.center == 0) + if MPI is not None: + MPI.barrier() + xmps.save_data() + if MPI is not None: + MPI.barrier() + _print(cf + ' -> ' + xmps.canonical_form) + else: + xmps = mps + + xmps.info.load_mutable() + xmps.load_mutable() + targetz = TrSX(xmps.info.target.n, xmps.info.target.twos, xmps.info.target.pg) + cp_mps = trans_mps(UnfusedMPS(xmps), copy_tag, mpo.tf.opf.cg, targetz) if "resolve_twosz" in dic: res_twosz = int(dic["resolve_twosz"]) cp_mps.resolve_singlet_embedding(res_twosz) diff --git a/pyblock2/driver/core.py b/pyblock2/driver/core.py index ebc5ccb3..5990be37 100644 --- a/pyblock2/driver/core.py +++ b/pyblock2/driver/core.py @@ -5554,12 +5554,11 @@ def get_npdm( op_str = "(C+D)0" for _ in range(pdm_type - 1): op_str = su2_coupling % op_str - if mask is None: - perm = bw.b.SpinPermScheme.initialize_su2(pdm_type * 2, op_str, True) - else: - perm = bw.b.SpinPermScheme.initialize_su2( - pdm_type * 2, op_str, True, mask=bw.b.VectorUInt16(mask) - ) + perm = bw.b.SpinPermScheme.initialize_su2( + pdm_type * 2, op_str, True, + mask=bw.b.VectorUInt16() if mask is None else bw.b.VectorUInt16(mask), + max_n_sites=ket.n_sites, + ) perms = bw.b.VectorSpinPermScheme([perm]) elif SymmetryTypes.SZ in bw.symm_type: if npdm_expr is not None and isinstance(npdm_expr, str): @@ -5573,10 +5572,10 @@ def get_npdm( if mask is None: perms = bw.b.VectorSpinPermScheme( [ - bw.b.SpinPermScheme.initialize_sz(pdm_type * 2, cd, True) - if fermionic_ops is None else - bw.b.SpinPermScheme.initialize_sany(pdm_type * 2, cd, fermionic_ops) - for cd in op_str + bw.b.SpinPermScheme.initialize_sz(pdm_type * 2, cd, True, + mask=bw.b.VectorUInt16(), max_n_sites=ket.n_sites) if fermionic_ops is None else + bw.b.SpinPermScheme.initialize_sany(pdm_type * 2, cd, fermionic_ops, + mask=bw.b.VectorUInt16(), max_n_sites=ket.n_sites) for cd in op_str ] ) elif len(mask) != 0 and not isinstance(mask[0], int): @@ -5587,10 +5586,10 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sz( - pt * 2, cd, True, mask=bw.b.VectorUInt16(xm) + pt * 2, cd, True, mask=bw.b.VectorUInt16(xm), max_n_sites=ket.n_sites ) if fermionic_ops is None else bw.b.SpinPermScheme.initialize_sany( - pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(xm) + pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(xm), max_n_sites=ket.n_sites ) for cd, xm, pt in zip(op_str, mask, pts) ] @@ -5602,10 +5601,10 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sz( - pt * 2, cd, True, mask=bw.b.VectorUInt16(mask) + pt * 2, cd, True, mask=bw.b.VectorUInt16(mask), max_n_sites=ket.n_sites ) if fermionic_ops is None else bw.b.SpinPermScheme.initialize_sany( - pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(mask) + pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(mask), max_n_sites=ket.n_sites ) for cd, pt in zip(op_str, pts) ] @@ -5620,10 +5619,10 @@ def get_npdm( if mask is None: perms = bw.b.VectorSpinPermScheme( [ - bw.b.SpinPermScheme.initialize_sz(pdm_type * 2, cd, True) - if fermionic_ops is None else - bw.b.SpinPermScheme.initialize_sany(pdm_type * 2, cd, fermionic_ops) - for cd in op_str + bw.b.SpinPermScheme.initialize_sz(pdm_type * 2, cd, True, + mask=bw.b.VectorUInt16(), max_n_sites=ket.n_sites) if fermionic_ops is None else + bw.b.SpinPermScheme.initialize_sany(pdm_type * 2, cd, fermionic_ops, + mask=bw.b.VectorUInt16(), max_n_sites=ket.n_sites) for cd in op_str ] ) elif len(mask) != 0 and not isinstance(mask[0], int): @@ -5634,10 +5633,10 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sz( - pt * 2, cd, True, mask=bw.b.VectorUInt16(xm) + pt * 2, cd, True, mask=bw.b.VectorUInt16(xm), max_n_sites=ket.n_sites ) if fermionic_ops is None else bw.b.SpinPermScheme.initialize_sany( - pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(xm) + pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(xm), max_n_sites=ket.n_sites ) for cd, xm, pt in zip(op_str, mask, pts) ] @@ -5649,10 +5648,10 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sz( - pt * 2, cd, True, mask=bw.b.VectorUInt16(mask) + pt * 2, cd, True, mask=bw.b.VectorUInt16(mask), max_n_sites=ket.n_sites ) if fermionic_ops is None else bw.b.SpinPermScheme.initialize_sany( - pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(mask) + pt * 2, cd, fermionic_ops, mask=bw.b.VectorUInt16(mask), max_n_sites=ket.n_sites ) for cd, pt in zip(op_str, pts) ] @@ -5664,8 +5663,8 @@ def get_npdm( if mask is None: perms = bw.b.VectorSpinPermScheme( [ - bw.b.SpinPermScheme.initialize_sany(len(cd), cd, fermionic_ops) - for cd in op_str + bw.b.SpinPermScheme.initialize_sany(len(cd), cd, fermionic_ops, + mask=bw.b.VectorUInt16(), max_n_sites=ket.n_sites) for cd in op_str ] ) elif len(mask) != 0 and not isinstance(mask[0], int): @@ -5673,7 +5672,7 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sany( - len(cd), cd, fermionic_ops, mask=bw.b.VectorUInt16(xm) + len(cd), cd, fermionic_ops, mask=bw.b.VectorUInt16(xm), max_n_sites=ket.n_sites ) for cd, xm in zip(op_str, mask) ] @@ -5682,7 +5681,7 @@ def get_npdm( perms = bw.b.VectorSpinPermScheme( [ bw.b.SpinPermScheme.initialize_sany( - len(cd), cd, fermionic_ops, mask=bw.b.VectorUInt16(mask) + len(cd), cd, fermionic_ops, mask=bw.b.VectorUInt16(mask), max_n_sites=ket.n_sites ) for cd in op_str ] @@ -5924,6 +5923,20 @@ def get_4pdm(self, ket, *args, **kwargs): """ return self.get_npdm(ket, pdm_type=4, *args, **kwargs) + def get_5pdm(self, ket, *args, **kwargs): + """ + Compute the 5-Particle Density Matrix (5PDM) for the given MPS. + See ``DMRGDriver.get_npdm``. + """ + return self.get_npdm(ket, pdm_type=5, *args, **kwargs) + + def get_6pdm(self, ket, *args, **kwargs): + """ + Compute the 6-Particle Density Matrix (6PDM) for the given MPS. + See ``DMRGDriver.get_npdm``. + """ + return self.get_npdm(ket, pdm_type=6, *args, **kwargs) + def get_trans_1pdm(self, bra, ket, *args, **kwargs): """ Compute the Transition 1-Particle Density Matrix (T-1PDM) @@ -5960,6 +5973,24 @@ def get_trans_4pdm(self, bra, ket, *args, **kwargs): """ return self.get_npdm(ket, pdm_type=4, bra=bra, *args, **kwargs) + def get_trans_5pdm(self, bra, ket, *args, **kwargs): + """ + Compute the Transition 5-Particle Density Matrix (T-5PDM) + between the given bra and ket MPSs. + Note that there can be an overall phase uncertainty for transition NPDMs. + See ``DMRGDriver.get_npdm``. + """ + return self.get_npdm(ket, pdm_type=5, bra=bra, *args, **kwargs) + + def get_trans_6pdm(self, bra, ket, *args, **kwargs): + """ + Compute the Transition 6-Particle Density Matrix (T-6PDM) + between the given bra and ket MPSs. + Note that there can be an overall phase uncertainty for transition NPDMs. + See ``DMRGDriver.get_npdm``. + """ + return self.get_npdm(ket, pdm_type=6, bra=bra, *args, **kwargs) + def get_csf_coefficients( self, ket, cutoff=0.1, given_dets=None, max_print=200, fci_conv=False, iprint=1 ): diff --git a/pyblock2/main_test/.gitignore b/pyblock2/main_test/.gitignore new file mode 100644 index 00000000..fa929750 --- /dev/null +++ b/pyblock2/main_test/.gitignore @@ -0,0 +1 @@ +*.out \ No newline at end of file diff --git a/pyblock2/main_test/000-check.py b/pyblock2/main_test/000-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/000-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/000-main.in b/pyblock2/main_test/000-main.in new file mode 100644 index 00000000..d548b549 --- /dev/null +++ b/pyblock2/main_test/000-main.in @@ -0,0 +1,15 @@ +# Ground State DMRG + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 \ No newline at end of file diff --git a/pyblock2/main_test/001-check.py b/pyblock2/main_test/001-check.py new file mode 100644 index 00000000..36ae7608 --- /dev/null +++ b/pyblock2/main_test/001-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.959626154680) < 1E-6 diff --git a/pyblock2/main_test/001-main.in b/pyblock2/main_test/001-main.in new file mode 100644 index 00000000..ed1f5970 --- /dev/null +++ b/pyblock2/main_test/001-main.in @@ -0,0 +1,15 @@ +# DMRG Targeting States + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 4 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/002-check.py b/pyblock2/main_test/002-check.py new file mode 100644 index 00000000..ef9e02ca --- /dev/null +++ b/pyblock2/main_test/002-check.py @@ -0,0 +1,14 @@ +import sys, struct + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/002-main.in b/pyblock2/main_test/002-main.in new file mode 100644 index 00000000..a7b160d5 --- /dev/null +++ b/pyblock2/main_test/002-main.in @@ -0,0 +1,17 @@ +# State-Average DMRG + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/003-check.py b/pyblock2/main_test/003-check.py new file mode 100644 index 00000000..1a02d153 --- /dev/null +++ b/pyblock2/main_test/003-check.py @@ -0,0 +1,11 @@ +import sys + +energies = [0.0] * 2 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy for root'): + idx = int(l.split()[-3]) + energies[idx] = float(l.split()[-1]) + +assert abs(energies[0] - -107.654122447525) < 1E-5 +assert abs(energies[1] - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/003-main.in b/pyblock2/main_test/003-main.in new file mode 100644 index 00000000..ae68f830 --- /dev/null +++ b/pyblock2/main_test/003-main.in @@ -0,0 +1,19 @@ +# State-Specific DMRG (ortho) +#DEP 2 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 +statespecific + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/004-check.py b/pyblock2/main_test/004-check.py new file mode 100644 index 00000000..1a02d153 --- /dev/null +++ b/pyblock2/main_test/004-check.py @@ -0,0 +1,11 @@ +import sys + +energies = [0.0] * 2 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy for root'): + idx = int(l.split()[-3]) + energies[idx] = float(l.split()[-1]) + +assert abs(energies[0] - -107.654122447525) < 1E-5 +assert abs(energies[1] - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/004-main.in b/pyblock2/main_test/004-main.in new file mode 100644 index 00000000..ba503984 --- /dev/null +++ b/pyblock2/main_test/004-main.in @@ -0,0 +1,20 @@ +# State-Specific DMRG (level-shift) +#DEP 2 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 +statespecific +proj_weights 5 5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/005-check.py b/pyblock2/main_test/005-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/005-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/005-main.in b/pyblock2/main_test/005-main.in new file mode 100644 index 00000000..f018652d --- /dev/null +++ b/pyblock2/main_test/005-main.in @@ -0,0 +1,16 @@ +# Direct level-shift DMRG ground state + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags KET1 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/006-check.py b/pyblock2/main_test/006-check.py new file mode 100644 index 00000000..36ae7608 --- /dev/null +++ b/pyblock2/main_test/006-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.959626154680) < 1E-6 diff --git a/pyblock2/main_test/006-main.in b/pyblock2/main_test/006-main.in new file mode 100644 index 00000000..68eb2a42 --- /dev/null +++ b/pyblock2/main_test/006-main.in @@ -0,0 +1,20 @@ +# Direct level-shift DMRG 1st excited state +#DEP 5 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags KET2 +num_thrds 4 +sweep_tol 1E-14 + +proj_mps_tags KET1 +proj_weights 5 \ No newline at end of file diff --git a/pyblock2/main_test/007-check.py b/pyblock2/main_test/007-check.py new file mode 100644 index 00000000..dc5b5ff6 --- /dev/null +++ b/pyblock2/main_test/007-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.94375693899154) < 1E-6 diff --git a/pyblock2/main_test/007-main.in b/pyblock2/main_test/007-main.in new file mode 100644 index 00000000..f1553a10 --- /dev/null +++ b/pyblock2/main_test/007-main.in @@ -0,0 +1,20 @@ +# Direct level-shift DMRG 2st excited state +#DEP 5 6 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags KET3 +num_thrds 4 +sweep_tol 1E-14 + +proj_mps_tags KET1 KET2 +proj_weights 5 5 \ No newline at end of file diff --git a/pyblock2/main_test/008-check.py b/pyblock2/main_test/008-check.py new file mode 100644 index 00000000..ef9e02ca --- /dev/null +++ b/pyblock2/main_test/008-check.py @@ -0,0 +1,14 @@ +import sys, struct + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/008-main.in b/pyblock2/main_test/008-main.in new file mode 100644 index 00000000..37e55dd7 --- /dev/null +++ b/pyblock2/main_test/008-main.in @@ -0,0 +1,21 @@ +# DMRG Mixed with State-Average (step 1) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags KET +num_thrds 4 +sweep_tol 1E-14 + +copy_mps +split_states diff --git a/pyblock2/main_test/009-check.py b/pyblock2/main_test/009-check.py new file mode 100644 index 00000000..dc84295c --- /dev/null +++ b/pyblock2/main_test/009-check.py @@ -0,0 +1,15 @@ +import sys, struct + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.94375693899154) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b, c = struct.unpack('ddd', f.read()) + assert abs(a - -106.9437569390) < 1E-5 + assert abs(b - -106.9304278080) < 1E-5 + assert abs(c - -106.8426967564) < 1E-5 diff --git a/pyblock2/main_test/009-main.in b/pyblock2/main_test/009-main.in new file mode 100644 index 00000000..be553779 --- /dev/null +++ b/pyblock2/main_test/009-main.in @@ -0,0 +1,25 @@ +# DMRG Mixed with State-Average (step 2) +#DEP 8 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 3 +weights 0.5 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags EXKET +num_thrds 4 +sweep_tol 1E-14 + +proj_mps_tags KET-0 KET-1 +proj_weights 5 5 + +copy_mps +split_states \ No newline at end of file diff --git a/pyblock2/main_test/010-check.py b/pyblock2/main_test/010-check.py new file mode 100644 index 00000000..1b78e590 --- /dev/null +++ b/pyblock2/main_test/010-check.py @@ -0,0 +1,9 @@ +import sys, struct + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.795333598887609) < 1E-6 diff --git a/pyblock2/main_test/010-main.in b/pyblock2/main_test/010-main.in new file mode 100644 index 00000000..1cfe09dc --- /dev/null +++ b/pyblock2/main_test/010-main.in @@ -0,0 +1,20 @@ +# DMRG Mixed with State-Average (step 3) +#DEP 8 9 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +mps_tags EXXKET +num_thrds 4 +sweep_tol 1E-14 + +proj_mps_tags KET-0 KET-1 EXKET-0 EXKET-1 EXKET-2 +proj_weights 5 5 5 5 5 diff --git a/pyblock2/main_test/011-check.py b/pyblock2/main_test/011-check.py new file mode 100644 index 00000000..965d5ebe --- /dev/null +++ b/pyblock2/main_test/011-check.py @@ -0,0 +1,43 @@ +import sys, os + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.FCI(mf) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym)) +assert abs(mx.e_tot + ecore - -107.654122447525) < 1E-6 + +dm1, dm2 = mx.make_rdm12(mx.ci, mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm.npy') +xdm1 = xdm1[0] + xdm1[1] + +assert np.linalg.norm(dm1 - xdm1) < 1E-5 + +xdm2 = np.load('./node0/2pdm.npy') +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert np.linalg.norm(dm2 - xdm2.transpose(0, 3, 1, 2)) < 1E-4 diff --git a/pyblock2/main_test/011-main.in b/pyblock2/main_test/011-main.in new file mode 100644 index 00000000..5566e0a4 --- /dev/null +++ b/pyblock2/main_test/011-main.in @@ -0,0 +1,18 @@ +# DMRG with 1PDM 2PDM + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +onepdm +twopdm \ No newline at end of file diff --git a/pyblock2/main_test/012-check.py b/pyblock2/main_test/012-check.py new file mode 100644 index 00000000..dd8321b6 --- /dev/null +++ b/pyblock2/main_test/012-check.py @@ -0,0 +1,50 @@ +import sys, struct, os + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym), nroots=4) +assert abs(mx.e_tot[0] + ecore - -107.654122447525) < 1E-6 +assert abs(mx.e_tot[1] + ecore - -106.959626154680) < 1E-6 + +for ir in range(2): + dm1, dm2 = mx.make_rdm12(mx.ci[ir], mf.mol.nao, mf.mol.nelec) + + xdm1 = np.load('./node0/1pdm-%d-%d.npy' % (ir, ir)) + xdm1 = xdm1[0] + xdm1[1] + + assert np.linalg.norm(dm1 - xdm1) < 1E-5 + + xdm2 = np.load('./node0/2pdm-%d-%d.npy' % (ir, ir)) + xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + + assert np.linalg.norm(dm2 - xdm2.transpose(0, 3, 1, 2)) < 1E-4 diff --git a/pyblock2/main_test/012-main.in b/pyblock2/main_test/012-main.in new file mode 100644 index 00000000..b558fb2d --- /dev/null +++ b/pyblock2/main_test/012-main.in @@ -0,0 +1,20 @@ +# DMRG with 1PDM 2PDM state-average + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +onepdm +twopdm \ No newline at end of file diff --git a/pyblock2/main_test/013-check.py b/pyblock2/main_test/013-check.py new file mode 100644 index 00000000..d0417dca --- /dev/null +++ b/pyblock2/main_test/013-check.py @@ -0,0 +1,49 @@ +import sys, struct, os + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym), nroots=4) +assert abs(mx.e_tot[0] + ecore - -107.654122447525) < 1E-6 +assert abs(mx.e_tot[1] + ecore - -106.959626154680) < 1E-6 + +dm1, dm2 = mx.trans_rdm12(mx.ci[0], mx.ci[1], mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm-%d-%d.npy' % (0, 1)) +xdm1 = xdm1[0] + xdm1[1] + +assert min(np.linalg.norm(dm1 - f * xdm1) for f in [1, -1]) < 1E-5 + +xdm2 = np.load('./node0/2pdm-%d-%d.npy' % (0, 1)) +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert min(np.linalg.norm(dm2 - f * xdm2.transpose(0, 3, 1, 2)) for f in [1, -1]) < 1E-4 diff --git a/pyblock2/main_test/013-main.in b/pyblock2/main_test/013-main.in new file mode 100644 index 00000000..99e353ca --- /dev/null +++ b/pyblock2/main_test/013-main.in @@ -0,0 +1,20 @@ +# DMRG with trans 2PDM state-average + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +tran_onepdm +tran_twopdm \ No newline at end of file diff --git a/pyblock2/main_test/014-check.py b/pyblock2/main_test/014-check.py new file mode 100644 index 00000000..c1d2af4d --- /dev/null +++ b/pyblock2/main_test/014-check.py @@ -0,0 +1,46 @@ +import sys, os + +energies = [0.0] * 2 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy for root'): + idx = int(l.split()[-3]) + energies[idx] = float(l.split()[-1]) + +assert abs(energies[0] - -107.654122447525) < 1E-5 +assert abs(energies[1] - -106.959626154680) < 1E-5 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True, verbose=0) +mf.mol.symmetry = True + +mx = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym), nroots=4) +assert abs(mx.e_tot[0] + ecore - -107.654122447525) < 1E-6 +assert abs(mx.e_tot[1] + ecore - -106.959626154680) < 1E-6 + +dm1, dm2 = mx.trans_rdm12(mx.ci[0], mx.ci[1], mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm-%d-%d.npy' % (0, 1)) +xdm1 = xdm1[0] + xdm1[1] + +assert min(np.linalg.norm(dm1 - f * xdm1) for f in [1, -1]) < 1E-5 + +xdm2 = np.load('./node0/2pdm-%d-%d.npy' % (0, 1)) +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert min(np.linalg.norm(dm2 - f * xdm2.transpose(0, 3, 1, 2)) for f in [1, -1]) < 1E-4 diff --git a/pyblock2/main_test/014-main.in b/pyblock2/main_test/014-main.in new file mode 100644 index 00000000..f7479c31 --- /dev/null +++ b/pyblock2/main_test/014-main.in @@ -0,0 +1,22 @@ +# DMRG with trans 2PDM refined +#DEP 13 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 +statespecific + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +tran_onepdm +tran_twopdm \ No newline at end of file diff --git a/pyblock2/main_test/015-check.py b/pyblock2/main_test/015-check.py new file mode 100644 index 00000000..94d527b3 --- /dev/null +++ b/pyblock2/main_test/015-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654) < 1E-3 diff --git a/pyblock2/main_test/015-main.in b/pyblock2/main_test/015-main.in new file mode 100644 index 00000000..f8ccdae7 --- /dev/null +++ b/pyblock2/main_test/015-main.in @@ -0,0 +1,18 @@ +# DMRG restart (first step) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule +0 50 1E-4 1E-3 +4 70 1E-4 1E-3 +end +twodot_to_onedot 6 +maxiter 10 +num_thrds 4 +sweep_tol 1E-14 diff --git a/pyblock2/main_test/016-check.py b/pyblock2/main_test/016-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/016-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/016-main.in b/pyblock2/main_test/016-main.in new file mode 100644 index 00000000..3074366f --- /dev/null +++ b/pyblock2/main_test/016-main.in @@ -0,0 +1,22 @@ +# DMRG restart (second step) +#DEP 15 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule +0 70 1E-4 1E-3 +4 200 1E-5 1E-6 +8 500 1E-8 0E+0 +end +twodot_to_onedot 10 +maxiter 16 +num_thrds 4 +sweep_tol 1E-14 + +fullrestart \ No newline at end of file diff --git a/pyblock2/main_test/017-check.py b/pyblock2/main_test/017-check.py new file mode 100644 index 00000000..d6813ef0 --- /dev/null +++ b/pyblock2/main_test/017-check.py @@ -0,0 +1,31 @@ + +import os + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.FCI(mf) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym)) +assert abs(mx.e_tot + ecore - -107.654122447525) < 1E-6 + +dm1, dm2 = mx.make_rdm12(mx.ci, mf.mol.nao, mf.mol.nelec) + +xdm2 = np.load('./node0/2pdm.npy') +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert np.linalg.norm(dm2 - xdm2.transpose(0, 3, 1, 2)) < 1E-4 diff --git a/pyblock2/main_test/017-main.in b/pyblock2/main_test/017-main.in new file mode 100644 index 00000000..d2c70597 --- /dev/null +++ b/pyblock2/main_test/017-main.in @@ -0,0 +1,18 @@ +# DMRG restart for 2pdm +#DEP 0 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +restart_twopdm \ No newline at end of file diff --git a/pyblock2/main_test/018-check.py b/pyblock2/main_test/018-check.py new file mode 100644 index 00000000..5a0083ec --- /dev/null +++ b/pyblock2/main_test/018-check.py @@ -0,0 +1,41 @@ +import struct, os + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym), nroots=4) +assert abs(mx.e_tot[0] + ecore - -107.654122447525) < 1E-6 +assert abs(mx.e_tot[1] + ecore - -106.959626154680) < 1E-6 + +dm1, dm2 = mx.trans_rdm12(mx.ci[0], mx.ci[1], mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm-%d-%d.npy' % (0, 1)) +xdm1 = xdm1[0] + xdm1[1] + +assert min(np.linalg.norm(dm1 - f * xdm1) for f in [1, -1]) < 1E-5 + +xdm2 = np.load('./node0/2pdm-%d-%d.npy' % (0, 1)) +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert min(np.linalg.norm(dm2 - f * xdm2.transpose(0, 3, 1, 2)) for f in [1, -1]) < 1E-4 diff --git a/pyblock2/main_test/018-main.in b/pyblock2/main_test/018-main.in new file mode 100644 index 00000000..6d49af4b --- /dev/null +++ b/pyblock2/main_test/018-main.in @@ -0,0 +1,21 @@ +# State-Averaged DMRG restart for tran 2pdm +#DEP 2 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +nroots 2 +weights 0.5 0.5 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +restart_tran_onepdm +restart_tran_twopdm \ No newline at end of file diff --git a/pyblock2/main_test/019-check.py b/pyblock2/main_test/019-check.py new file mode 100644 index 00000000..303ac8bd --- /dev/null +++ b/pyblock2/main_test/019-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.116397543375) < 1E-6 diff --git a/pyblock2/main_test/019-main.in b/pyblock2/main_test/019-main.in new file mode 100644 index 00000000..69fd6d76 --- /dev/null +++ b/pyblock2/main_test/019-main.in @@ -0,0 +1,17 @@ +# DMRG tran 2pdm (diff irrep, step 1) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 2 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +mps_tags KET \ No newline at end of file diff --git a/pyblock2/main_test/020-check.py b/pyblock2/main_test/020-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/020-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/020-main.in b/pyblock2/main_test/020-main.in new file mode 100644 index 00000000..8acb599b --- /dev/null +++ b/pyblock2/main_test/020-main.in @@ -0,0 +1,17 @@ +# DMRG tran 2pdm (diff irrep, step 2) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +mps_tags BRA \ No newline at end of file diff --git a/pyblock2/main_test/021-check.py b/pyblock2/main_test/021-check.py new file mode 100644 index 00000000..f18959cb --- /dev/null +++ b/pyblock2/main_test/021-check.py @@ -0,0 +1,41 @@ + +import os + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=7, orbsym=np.array(driver.orb_sym), nroots=1) + +mx2 = fci.addons.fix_spin_(fci.FCI(mf), ss=0) +mx2.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym), nroots=1) +assert abs(mx2.e_tot + ecore - -107.654122447525) < 1E-6 +assert abs(mx.e_tot + ecore - -107.116397543375) < 1E-6 + +dm1, dm2 = mx.trans_rdm12(mx.ci, mx2.ci, mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm-%d-%d.npy' % (0, 1)) +xdm1 = xdm1[0] + xdm1[1] + +assert min(np.linalg.norm(dm1 - f * xdm1) for f in [1, -1]) < 1E-5 + +xdm2 = np.load('./node0/2pdm-%d-%d.npy' % (0, 1)) +xdm2 = xdm2[0] + xdm2[2] + xdm2[1] + xdm2[1].transpose(1, 0, 3, 2) + +assert min(np.linalg.norm(dm2 - f * xdm2.transpose(3, 0, 2, 1)) for f in [1, -1]) < 1E-4 diff --git a/pyblock2/main_test/021-main.in b/pyblock2/main_test/021-main.in new file mode 100644 index 00000000..36c4138a --- /dev/null +++ b/pyblock2/main_test/021-main.in @@ -0,0 +1,21 @@ +# DMRG tran 2pdm (diff irrep, step 3) +#DEP 19 20 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 +mps_tags BRA KET + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +restart_tran_onepdm +restart_tran_twopdm +conventional_npdm \ No newline at end of file diff --git a/pyblock2/main_test/022-check.py b/pyblock2/main_test/022-check.py new file mode 100644 index 00000000..36a347ac --- /dev/null +++ b/pyblock2/main_test/022-check.py @@ -0,0 +1,47 @@ +import sys, os + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +if os.name == "nt": + quit() # pyscf not available on windows + +from pyblock2.driver.core import DMRGDriver, SymmetryTypes +from pyscf import fci +from pyscf.tools import fcidump +import numpy as np + +driver = DMRGDriver(scratch="./nodex", symm_type=SymmetryTypes.SU2, n_threads=4) +driver.read_fcidump(filename='../../data/N2.STO3G.FCIDUMP', pg='d2h', iprint=0) +driver.initialize_system(n_sites=driver.n_sites, n_elec=driver.n_elec, + spin=driver.spin, orb_sym=driver.orb_sym) +h1e, g2e, ecore = driver.h1e, driver.g2e, driver.ecore + +mf = fcidump.to_scf('../../data/N2.STO3G.FCIDUMP', molpro_orbsym=True) +mf.mol.symmetry = True + +mx = fci.FCI(mf) +mx.kernel(h1e, g2e, driver.n_sites, driver.n_elec, tol=1e-12, + wfnsym=0, orbsym=np.array(driver.orb_sym)) +assert abs(mx.e_tot + ecore - -107.654122447525) < 1E-6 + +dm1, dm2 = mx.make_rdm12(mx.ci, mf.mol.nao, mf.mol.nelec) + +xdm1 = np.load('./node0/1pdm.npy') +xdm1 = xdm1[0] + xdm1[1] + +assert np.linalg.norm(dm1 - xdm1) < 1E-5 + +_e_pqqp = np.load('./node0/e_pqqp.npy') +_e_pqpq = np.load('./node0/e_pqpq.npy') +_2pdm_spat = dm2.transpose(0, 2, 3, 1) +_2pdm_spat_pqqp = np.einsum('pqqp->pq', _2pdm_spat) +_2pdm_spat_pqpq = np.einsum('pqpq->pq', _2pdm_spat) + +assert np.linalg.norm(_e_pqqp - _2pdm_spat_pqqp) < 1E-5 +assert np.linalg.norm(_e_pqpq - _2pdm_spat_pqpq) < 1E-5 diff --git a/pyblock2/main_test/022-main.in b/pyblock2/main_test/022-main.in new file mode 100644 index 00000000..f0963aa9 --- /dev/null +++ b/pyblock2/main_test/022-main.in @@ -0,0 +1,17 @@ +# DMRG diag 2pdm + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +diag_twopdm \ No newline at end of file diff --git a/pyblock2/main_test/023-check.py b/pyblock2/main_test/023-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/023-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/023-main.in b/pyblock2/main_test/023-main.in new file mode 100644 index 00000000..926726e6 --- /dev/null +++ b/pyblock2/main_test/023-main.in @@ -0,0 +1,23 @@ +# Ground State DMRG (custom schedule) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule +0 100 1E-4 1E-3 +4 250 1E-4 1E-3 +8 400 1E-5 1E-4 +10 600 1E-6 1E-5 +12 800 1E-7 1E-6 +14 1000 1E-8 1E-7 +16 1000 1E-8 0E+0 +end +twodot_to_onedot 18 +maxiter 100 +num_thrds 4 +sweep_tol 1E-14 \ No newline at end of file diff --git a/pyblock2/main_test/024-check.py b/pyblock2/main_test/024-check.py new file mode 100644 index 00000000..e545ddb7 --- /dev/null +++ b/pyblock2/main_test/024-check.py @@ -0,0 +1,20 @@ +import sys + +eners, dws = [], [] + +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if "DW" in l: + eners.append(float(l.split()[7])) + dws.append(float(l.split()[-1])) + +eners, dws = eners[3::4], dws[3::4] + +import scipy.stats +reg = scipy.stats.linregress(dws, eners) + +assert abs(eners[0] - -107.6541224474) < 1E-6 +assert abs(eners[1] - -107.6541224425) < 1E-6 +assert abs(eners[2] - -107.6541223606) < 1E-6 +assert abs(eners[3] - -107.6541219540) < 1E-6 +assert abs(reg.intercept - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/024-main.in b/pyblock2/main_test/024-main.in new file mode 100644 index 00000000..e8fedc70 --- /dev/null +++ b/pyblock2/main_test/024-main.in @@ -0,0 +1,22 @@ +# Ground State DMRG (reverse schedule) +#DEP 23 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +twodot +schedule +0 35 1E-8 0E+0 +4 30 1E-8 0E+0 +8 25 1E-8 0E+0 +12 20 1E-8 0E+0 +end +maxiter 16 +num_thrds 4 +sweep_tol 0.0 +fullrestart \ No newline at end of file diff --git a/pyblock2/main_test/025-check.py b/pyblock2/main_test/025-check.py new file mode 100644 index 00000000..b848c747 --- /dev/null +++ b/pyblock2/main_test/025-check.py @@ -0,0 +1,13 @@ +import sys + +energy = 0 +nat_occ = [] +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + if l.startswith('REORDERED NAT OCC ='): + nat_occ = [float(x) for x in l.split()[4:]] + +assert abs(energy - -107.654122447525) < 1E-6 +assert abs(nat_occ[0] - 1.999995) < 1E-4 diff --git a/pyblock2/main_test/025-main.in b/pyblock2/main_test/025-main.in new file mode 100644 index 00000000..93eeeefa --- /dev/null +++ b/pyblock2/main_test/025-main.in @@ -0,0 +1,21 @@ +# Orbital Rotation (step 1) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +onepdm +irrep_reorder +nat_orbs ./nodex/N2.NAT.FCIDUMP +nat_km_reorder +nat_positive_def \ No newline at end of file diff --git a/pyblock2/main_test/026-check.py b/pyblock2/main_test/026-check.py new file mode 100644 index 00000000..49dfc92d --- /dev/null +++ b/pyblock2/main_test/026-check.py @@ -0,0 +1,7 @@ +import sys + +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if '' in l: + norm_sq = float(l.split()[-1]) + assert abs(norm_sq - 1.0) < 1E-6 diff --git a/pyblock2/main_test/026-main.in b/pyblock2/main_test/026-main.in new file mode 100644 index 00000000..3e2fb1de --- /dev/null +++ b/pyblock2/main_test/026-main.in @@ -0,0 +1,21 @@ +# Orbital Rotation (step 2) +#DEP 25 + +sym d2h + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule + 0 1000 0 0 +end +num_thrds 4 + +mps_tags BRA +orbital_rotation +delta_t 0.05 +outputlevel 1 +noreorder + diff --git a/pyblock2/main_test/027-check.py b/pyblock2/main_test/027-check.py new file mode 100644 index 00000000..69e01457 --- /dev/null +++ b/pyblock2/main_test/027-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/027-main.in b/pyblock2/main_test/027-main.in new file mode 100644 index 00000000..0ebe6cfc --- /dev/null +++ b/pyblock2/main_test/027-main.in @@ -0,0 +1,21 @@ +# Orbital Rotation (step 3) +#DEP 25 26 + +sym d2h +orbitals ./nodex/N2.NAT.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +mps_tags BRA +restart_oh +restart_onepdm +noreorder diff --git a/pyblock2/main_test/028-check.py b/pyblock2/main_test/028-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/028-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/028-main.in b/pyblock2/main_test/028-main.in new file mode 100644 index 00000000..84bcbe44 --- /dev/null +++ b/pyblock2/main_test/028-main.in @@ -0,0 +1,18 @@ +# MPS SU2 to SZ (step 1) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags KET \ No newline at end of file diff --git a/pyblock2/main_test/029-check.py b/pyblock2/main_test/029-check.py new file mode 100644 index 00000000..e69de29b diff --git a/pyblock2/main_test/029-main.in b/pyblock2/main_test/029-main.in new file mode 100644 index 00000000..828fd6fc --- /dev/null +++ b/pyblock2/main_test/029-main.in @@ -0,0 +1,21 @@ +# MPS SU2 to SZ (step 2) +#DEP 28 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags KET +restart_copy_mps ZKET +trans_mps_to_sz diff --git a/pyblock2/main_test/030-check.py b/pyblock2/main_test/030-check.py new file mode 100644 index 00000000..69e01457 --- /dev/null +++ b/pyblock2/main_test/030-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/030-main.in b/pyblock2/main_test/030-main.in new file mode 100644 index 00000000..49d7d4de --- /dev/null +++ b/pyblock2/main_test/030-main.in @@ -0,0 +1,21 @@ +# MPS SU2 to SZ (step 3) +#DEP 28 29 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags ZKET +restart_oh +nonspinadapted diff --git a/pyblock2/main_test/031-check.py b/pyblock2/main_test/031-check.py new file mode 100644 index 00000000..43b0797c --- /dev/null +++ b/pyblock2/main_test/031-check.py @@ -0,0 +1,13 @@ +import sys + +energy = 0 +quantum = '' +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + elif l.startswith('MPS ='): + quantum = l.split('< ')[-1].split(' >')[0] + +assert abs(energy - -106.939132859667396) < 1E-6 +assert quantum == 'N=14 S=1 PG=0' diff --git a/pyblock2/main_test/031-main.in b/pyblock2/main_test/031-main.in new file mode 100644 index 00000000..dc52dd53 --- /dev/null +++ b/pyblock2/main_test/031-main.in @@ -0,0 +1,18 @@ +# DMRG Non-singlet-embedding + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags KET \ No newline at end of file diff --git a/pyblock2/main_test/032-check.py b/pyblock2/main_test/032-check.py new file mode 100644 index 00000000..947bec38 --- /dev/null +++ b/pyblock2/main_test/032-check.py @@ -0,0 +1,13 @@ +import sys + +energy = 0 +quantum = '' +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + elif l.startswith('MPS ='): + quantum = l.split('< ')[-1].split(' >')[0] + +assert abs(energy - -106.939132859667396) < 1E-6 +assert quantum == 'N=16 S=0 PG=0' diff --git a/pyblock2/main_test/032-main.in b/pyblock2/main_test/032-main.in new file mode 100644 index 00000000..43d6fc29 --- /dev/null +++ b/pyblock2/main_test/032-main.in @@ -0,0 +1,19 @@ +# DMRG Singlet-embedding (even sweeps) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 0 + +irrep_reorder +mps_tags SEKET +singlet_embedding \ No newline at end of file diff --git a/pyblock2/main_test/033-check.py b/pyblock2/main_test/033-check.py new file mode 100644 index 00000000..e69de29b diff --git a/pyblock2/main_test/033-main.in b/pyblock2/main_test/033-main.in new file mode 100644 index 00000000..2da6f40c --- /dev/null +++ b/pyblock2/main_test/033-main.in @@ -0,0 +1,21 @@ +# DMRG SE to NSE +#DEP 32 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags SEKET +restart_copy_mps TKET +trans_mps_from_singlet_embedding \ No newline at end of file diff --git a/pyblock2/main_test/034-check.py b/pyblock2/main_test/034-check.py new file mode 100644 index 00000000..7584e4e8 --- /dev/null +++ b/pyblock2/main_test/034-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.939132859667396) < 1E-6 diff --git a/pyblock2/main_test/034-main.in b/pyblock2/main_test/034-main.in new file mode 100644 index 00000000..c60edd8a --- /dev/null +++ b/pyblock2/main_test/034-main.in @@ -0,0 +1,20 @@ +# DMRG NSE Expectation +#DEP 32 33 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags TKET +restart_oh \ No newline at end of file diff --git a/pyblock2/main_test/035-check.py b/pyblock2/main_test/035-check.py new file mode 100644 index 00000000..e69de29b diff --git a/pyblock2/main_test/035-main.in b/pyblock2/main_test/035-main.in new file mode 100644 index 00000000..3cdda9d0 --- /dev/null +++ b/pyblock2/main_test/035-main.in @@ -0,0 +1,23 @@ +# DMRG SE SU2 to SZ +#DEP 32 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags SEKET +restart_copy_mps ZKETM2 +trans_mps_to_sz +resolve_twosz -2 +normalize_mps \ No newline at end of file diff --git a/pyblock2/main_test/036-check.py b/pyblock2/main_test/036-check.py new file mode 100644 index 00000000..7584e4e8 --- /dev/null +++ b/pyblock2/main_test/036-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.939132859667396) < 1E-6 diff --git a/pyblock2/main_test/036-main.in b/pyblock2/main_test/036-main.in new file mode 100644 index 00000000..c2137b74 --- /dev/null +++ b/pyblock2/main_test/036-main.in @@ -0,0 +1,21 @@ +# DMRG SE SU2 to SZ Expectation +#DEP 32 35 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin -2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags ZKETM2 +restart_oh +nonspinadapted \ No newline at end of file diff --git a/pyblock2/main_test/037-check.py b/pyblock2/main_test/037-check.py new file mode 100644 index 00000000..947bec38 --- /dev/null +++ b/pyblock2/main_test/037-check.py @@ -0,0 +1,13 @@ +import sys + +energy = 0 +quantum = '' +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + elif l.startswith('MPS ='): + quantum = l.split('< ')[-1].split(' >')[0] + +assert abs(energy - -106.939132859667396) < 1E-6 +assert quantum == 'N=16 S=0 PG=0' diff --git a/pyblock2/main_test/037-main.in b/pyblock2/main_test/037-main.in new file mode 100644 index 00000000..68e1ee10 --- /dev/null +++ b/pyblock2/main_test/037-main.in @@ -0,0 +1,19 @@ +# DMRG Singlet-embedding (odd sweeps) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 29 +num_thrds 4 +sweep_tol 0 + +irrep_reorder +mps_tags SEKET +singlet_embedding \ No newline at end of file diff --git a/pyblock2/main_test/038-check.py b/pyblock2/main_test/038-check.py new file mode 100644 index 00000000..e69de29b diff --git a/pyblock2/main_test/038-main.in b/pyblock2/main_test/038-main.in new file mode 100644 index 00000000..0cf428c0 --- /dev/null +++ b/pyblock2/main_test/038-main.in @@ -0,0 +1,23 @@ +# DMRG SE SU2 to SZ (odd sweeps) +#DEP 37 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags SEKET +restart_copy_mps ZKETM2 +trans_mps_to_sz +resolve_twosz -2 +normalize_mps \ No newline at end of file diff --git a/pyblock2/main_test/039-check.py b/pyblock2/main_test/039-check.py new file mode 100644 index 00000000..7584e4e8 --- /dev/null +++ b/pyblock2/main_test/039-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -106.939132859667396) < 1E-6 diff --git a/pyblock2/main_test/039-main.in b/pyblock2/main_test/039-main.in new file mode 100644 index 00000000..db7b0d50 --- /dev/null +++ b/pyblock2/main_test/039-main.in @@ -0,0 +1,21 @@ +# DMRG SE SU2 to SZ Expectation (odd sweeps) +#DEP 37 38 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin -2 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags ZKETM2 +restart_oh +nonspinadapted \ No newline at end of file diff --git a/pyblock2/main_test/040-check.py b/pyblock2/main_test/040-check.py new file mode 100644 index 00000000..7c1a7113 --- /dev/null +++ b/pyblock2/main_test/040-check.py @@ -0,0 +1,18 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +import numpy as np + +dets = np.load('node0/sample-dets.npy') +vals = np.load('node0/sample-vals.npy') + +idx = np.argsort(np.abs(vals))[-1] +assert np.all(dets[idx] == [3] * 5 + [0, 3] * 2 + [0]) +assert abs(abs(vals[idx]) - 0.957506527063957) < 1E-4 diff --git a/pyblock2/main_test/040-main.in b/pyblock2/main_test/040-main.in new file mode 100644 index 00000000..e9bff7d2 --- /dev/null +++ b/pyblock2/main_test/040-main.in @@ -0,0 +1,19 @@ +# DMRG CSF Coefficients + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags KET +sample 0.05 \ No newline at end of file diff --git a/pyblock2/main_test/041-check.py b/pyblock2/main_test/041-check.py new file mode 100644 index 00000000..7c1a7113 --- /dev/null +++ b/pyblock2/main_test/041-check.py @@ -0,0 +1,18 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +import numpy as np + +dets = np.load('node0/sample-dets.npy') +vals = np.load('node0/sample-vals.npy') + +idx = np.argsort(np.abs(vals))[-1] +assert np.all(dets[idx] == [3] * 5 + [0, 3] * 2 + [0]) +assert abs(abs(vals[idx]) - 0.957506527063957) < 1E-4 diff --git a/pyblock2/main_test/041-main.in b/pyblock2/main_test/041-main.in new file mode 100644 index 00000000..0fde2cd3 --- /dev/null +++ b/pyblock2/main_test/041-main.in @@ -0,0 +1,20 @@ +# DMRG DET Coefficients + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder +mps_tags KET +sample 0.05 +nonspinadapted \ No newline at end of file diff --git a/pyblock2/main_test/042-check.py b/pyblock2/main_test/042-check.py new file mode 100644 index 00000000..4688cebb --- /dev/null +++ b/pyblock2/main_test/042-check.py @@ -0,0 +1,9 @@ +import sys + +ovlp = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('Compression overlap ='): + ovlp = float(l.split()[-1]) + +assert abs(ovlp - 0.957506527014452) < 1E-6 diff --git a/pyblock2/main_test/042-main.in b/pyblock2/main_test/042-main.in new file mode 100644 index 00000000..46b5726f --- /dev/null +++ b/pyblock2/main_test/042-main.in @@ -0,0 +1,31 @@ +# MPS Compression +#DEP 40 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule +0 250 0 0 +2 125 0 0 +4 62 0 0 +6 31 0 0 +8 15 0 0 +10 7 0 0 +12 3 0 0 +14 1 0 0 +end +maxiter 16 +num_thrds 4 +sweep_tol 0 + +compression +overlap +read_mps_tags KET +mps_tags BRA + +irrep_reorder diff --git a/pyblock2/main_test/043-check.py b/pyblock2/main_test/043-check.py new file mode 100644 index 00000000..fe4783dc --- /dev/null +++ b/pyblock2/main_test/043-check.py @@ -0,0 +1,9 @@ +import sys + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/043-main.in b/pyblock2/main_test/043-main.in new file mode 100644 index 00000000..9179f673 --- /dev/null +++ b/pyblock2/main_test/043-main.in @@ -0,0 +1,21 @@ +# DMRG occ init + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nelec 14 +spin 0 +irrep 1 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +irrep_reorder + +warmup occ +occ 2.000 1.991 1.985 2.000 1.986 0.020 1.931 0.077 1.931 0.077 +cbias 0.2 diff --git a/pyblock2/main_test/044-check.py b/pyblock2/main_test/044-check.py new file mode 100644 index 00000000..ef9e02ca --- /dev/null +++ b/pyblock2/main_test/044-check.py @@ -0,0 +1,14 @@ +import sys, struct + +energy = 0 +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('DMRG Energy ='): + energy = float(l.split()[-1]) + +assert abs(energy - -107.654122447525) < 1E-6 + +with open('node0/dmrg.e', 'rb') as f: + a, b = struct.unpack('dd', f.read()) + assert abs(a - -107.654122447525) < 1E-5 + assert abs(b - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/044-main.in b/pyblock2/main_test/044-main.in new file mode 100644 index 00000000..bc2a8403 --- /dev/null +++ b/pyblock2/main_test/044-main.in @@ -0,0 +1,15 @@ +# Time-dependent DMRG (step 1 - init) + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nroots 2 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +noreorder diff --git a/pyblock2/main_test/045-check.py b/pyblock2/main_test/045-check.py new file mode 100644 index 00000000..e69de29b diff --git a/pyblock2/main_test/045-main.in b/pyblock2/main_test/045-main.in new file mode 100644 index 00000000..aa8f474a --- /dev/null +++ b/pyblock2/main_test/045-main.in @@ -0,0 +1,19 @@ +# Time-dependent DMRG (step 2 - split) +#DEP 44 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +nroots 2 + +hf_occ integral +schedule default +maxM 500 +maxiter 30 +num_thrds 4 +sweep_tol 1E-14 + +restart_copy_mps +split_states +trans_mps_to_complex +noreorder diff --git a/pyblock2/main_test/046-check.py b/pyblock2/main_test/046-check.py new file mode 100644 index 00000000..4d1c6505 --- /dev/null +++ b/pyblock2/main_test/046-check.py @@ -0,0 +1,10 @@ +import sys, struct + +energies = [] +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('T = RE'): + energies.append(float(l.split()[9]) / float(l.split()[-1])) + +for energy in energies: + assert abs(energy - -107.654122447525) < 1E-6 diff --git a/pyblock2/main_test/046-main.in b/pyblock2/main_test/046-main.in new file mode 100644 index 00000000..70e2dbaf --- /dev/null +++ b/pyblock2/main_test/046-main.in @@ -0,0 +1,20 @@ +# Time-dependent DMRG (step 3 - root 0 td) +#DEP 44 45 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +hf_occ integral +schedule +0 40 0 0 +end +maxiter 10 +num_thrds 4 +sweep_tol 1E-14 + +read_mps_tags KET-CPX-0 +mps_tags BRA +delta_t 0.05i +target_t 0.20i +complex_mps +noreorder diff --git a/pyblock2/main_test/047-check.py b/pyblock2/main_test/047-check.py new file mode 100644 index 00000000..a2cd1982 --- /dev/null +++ b/pyblock2/main_test/047-check.py @@ -0,0 +1,10 @@ +import sys, struct + +energies = [] +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('T = RE'): + energies.append(float(l.split()[9]) / float(l.split()[-1])) + +for energy in energies: + assert abs(energy - -106.959626154680) < 1E-6 diff --git a/pyblock2/main_test/047-main.in b/pyblock2/main_test/047-main.in new file mode 100644 index 00000000..6ad0b0da --- /dev/null +++ b/pyblock2/main_test/047-main.in @@ -0,0 +1,20 @@ +# Time-dependent DMRG (step 4 - root 1 td) +#DEP 44 45 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +hf_occ integral +schedule +0 40 0 0 +end +maxiter 10 +num_thrds 4 +sweep_tol 1E-14 + +read_mps_tags KET-CPX-1 +mps_tags BRAEX +delta_t 0.05i +target_t 0.20i +complex_mps +noreorder diff --git a/pyblock2/main_test/048-check.py b/pyblock2/main_test/048-check.py new file mode 100644 index 00000000..5cdecb7f --- /dev/null +++ b/pyblock2/main_test/048-check.py @@ -0,0 +1,23 @@ +import sys +import numpy as np + +energies = np.zeros((4, 4), dtype=complex) +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy'): + a, b = [int(c) for c in l.split()[2:5:2]] + energies[a, b] = float(l.split()[-1]) * 1j + float(l.split()[-4]) + +np.save('node0/ovlps.npy', energies) + +x = energies[1, 0] / (energies[0, 0] * energies[1, 1]) ** 0.5 +ang = -107.654122447525 * 0.2 % (2 * np.pi) + +assert abs(np.abs(x) - 1.0) < 1E-6 +assert abs(abs(np.angle(x) - ang) - 2 * np.pi) < 1E-6 + +x = energies[3, 2] / (energies[2, 2] * energies[3, 3]) ** 0.5 +ang = -106.959626154680 * 0.2 % (2 * np.pi) + +assert abs(np.abs(x) - 1.0) < 1E-6 +assert abs(abs(np.angle(x) - ang) - 2 * np.pi) < 1E-6 diff --git a/pyblock2/main_test/048-main.in b/pyblock2/main_test/048-main.in new file mode 100644 index 00000000..23280f7a --- /dev/null +++ b/pyblock2/main_test/048-main.in @@ -0,0 +1,19 @@ +# Time-dependent DMRG (step 5 - overlap) +#DEP 44 45 46 47 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +hf_occ integral +schedule +0 40 0 0 +end +maxiter 10 +num_thrds 4 +sweep_tol 1E-14 + +mps_tags KET-CPX-0 BRA KET-CPX-1 BRAEX +restart_tran_oh +complex_mps +overlap +noreorder diff --git a/pyblock2/main_test/049-check.py b/pyblock2/main_test/049-check.py new file mode 100644 index 00000000..fc3dc181 --- /dev/null +++ b/pyblock2/main_test/049-check.py @@ -0,0 +1,16 @@ +import sys +import numpy as np + +energies = np.zeros((4, 4), dtype=complex) +with open(sys.argv[1], 'r') as f: + for l in f.readlines(): + if l.startswith('OH Energy'): + a, b = [int(c) for c in l.split()[2:5:2]] + energies[a, b] = float(l.split()[-1]) * 1j + float(l.split()[-4]) + +ovlps = np.load('node0/ovlps.npy') + +assert abs(energies[0, 0] / ovlps[0, 0] - -107.654122447525) < 1E-5 +assert abs(energies[1, 1] / ovlps[1, 1] - -107.654122447525) < 1E-5 +assert abs(energies[2, 2] / ovlps[2, 2] - -106.959626154680) < 1E-5 +assert abs(energies[3, 3] / ovlps[3, 3] - -106.959626154680) < 1E-5 diff --git a/pyblock2/main_test/049-main.in b/pyblock2/main_test/049-main.in new file mode 100644 index 00000000..36059db4 --- /dev/null +++ b/pyblock2/main_test/049-main.in @@ -0,0 +1,18 @@ +# Time-dependent DMRG (step 6 - energy) +#DEP 44 45 46 47 48 + +sym d2h +orbitals ../../data/N2.STO3G.FCIDUMP + +hf_occ integral +schedule +0 40 0 0 +end +maxiter 10 +num_thrds 4 +sweep_tol 1E-14 + +mps_tags KET-CPX-0 BRA KET-CPX-1 BRAEX +restart_tran_oh +complex_mps +noreorder diff --git a/pyblock2/main_test/run-test.ps1 b/pyblock2/main_test/run-test.ps1 new file mode 100755 index 00000000..23ffcb7e --- /dev/null +++ b/pyblock2/main_test/run-test.ps1 @@ -0,0 +1,47 @@ +#!/usr/bin/env pwsh + +for ($i = 0; $i -le 49; $i++) { + $formattedI = "{0:D3}" -f $i + $inputFile = "$formattedI-main.in" + $outputFile = "$formattedI-main.out" + + Write-Output "TEST $formattedI $(Get-Content -First 1 $inputFile)" + + $depLine = Get-Content $inputFile | Select-String -Pattern "#DEP" + $depLineProcessed = $depLine -replace "#DEP", "" -replace "^\s+", "" + $deps = $depLineProcessed -split "\s+" + + foreach ($j in $deps) { + $formattedJ = "{0:D3}" -f [int]$j + $depInputFile = "$formattedJ-main.in" + $depOutputFile = "$formattedJ-main.out" + + Write-Output "-- DEP $formattedJ $(Get-Content -First 1 $depInputFile)" + + python $env:block2main $depInputFile > $depOutputFile + if ($LASTEXITCODE -ne 0) { + Get-Content $depOutputFile | Write-Output + Write-Output "$formattedJ DEP FAILED!" + exit 3 + } + + python "$formattedJ-check.py" $depOutputFile + Remove-Item $depOutputFile + } + + python $env:block2main $inputFile > $outputFile + if ($LASTEXITCODE -ne 0) { + Get-Content $outputFile | Write-Output + Write-Output "$formattedI RUN FAILED!" + exit 1 + } + + python "$formattedI-check.py" $outputFile + if ($LASTEXITCODE -ne 0) { + Get-Content $outputFile | Write-Output + Write-Output "$formattedI WRONG NUMBER!" + exit 2 + } + + Remove-Item -Recurse $outputFile, "node0", "nodex" +} diff --git a/pyblock2/main_test/run-test.sh b/pyblock2/main_test/run-test.sh new file mode 100755 index 00000000..47c5c2a3 --- /dev/null +++ b/pyblock2/main_test/run-test.sh @@ -0,0 +1,35 @@ +#! /usr/bin/env bash + +if [ "x$1" != "x" ]; then + RANGE=$1 +else + RANGE=$(seq 0 49) +fi + +for i in $RANGE; do + echo "TEST $(printf "%03d" $i) " $(head -n 1 $(printf "%03d" $i)-main.in) + for j in $(grep "#DEP" $(printf "%03d" $i)-main.in | awk '{$1=""; print $0}'); do + echo -- DEP $(printf "%03d" $j) $(head -n 1 $(printf "%03d" $j)-main.in) + block2main $(printf "%03d" $j)-main.in > $(printf "%03d" $j)-main.out + if [ $? -ne 0 ]; then + cat $(printf "%03d" $j)-main.out + echo "$(printf "%03d" $j) DEP FAILED!" + exit 3 + fi + python3 $(printf "%03d" $j)-check.py $(printf "%03d" $j)-main.out + rm $(printf "%03d" $j)-main.out + done + block2main $(printf "%03d" $i)-main.in > $(printf "%03d" $i)-main.out + if [ $? -ne 0 ]; then + cat $(printf "%03d" $i)-main.out + echo "$(printf "%03d" $i) RUN FAILED!" + exit 1 + fi + python3 $(printf "%03d" $i)-check.py $(printf "%03d" $i)-main.out + if [ $? -ne 0 ]; then + cat $(printf "%03d" $i)-main.out + echo "$(printf "%03d" $i) WRONG NUMBER!" + exit 2 + fi + rm -r $(printf "%03d" $i)-main.out node0 nodex +done diff --git a/src/core/iterative_matrix_functions.hpp b/src/core/iterative_matrix_functions.hpp index e6e94c23..4b604b05 100644 --- a/src/core/iterative_matrix_functions.hpp +++ b/src/core/iterative_matrix_functions.hpp @@ -923,12 +923,21 @@ template struct IterativeMatrixFunctions : GMatrixFunctions { } for (int i = 0; i < k; i++) copy(bs[i], vs[i]); + int m = k; for (int i = 0; i < k; i++) { for (int j = 0; j < i; j++) iadd(bs[i], bs[j], -complex_dot(bs[j], bs[i])); - iscale(bs[i], (FP)1.0 / norm(bs[i])); + FL normx = norm(bs[i]); + if (abs(normx * normx) < 1E-14 && i > 0) { + m = i; + if (iprint) + cout << "Davidson: keeping only " << m << " initials." + << endl; + break; + } + iscale(bs[i], (FP)1.0 / normx); } - for (int i = 0; i < k; i++) { + for (int i = 0; i < m; i++) { for (int j = 0; j < nor; j++) if (abs(or_normsqs[j]) > 1E-14) iadd(bs[i], ors[j], @@ -949,7 +958,7 @@ template struct IterativeMatrixFunctions : GMatrixFunctions { GMatrix q(nullptr, bs[0].m, bs[0].n); if (pcomm == nullptr || pcomm->root == pcomm->rank) q.allocate(x_alloc); - int ck = 0, msig = 0, m = k, xiter = 0; + int ck = 0, msig = 0, xiter = 0; FL qq; if (iprint) cout << endl; @@ -1087,7 +1096,8 @@ template struct IterativeMatrixFunctions : GMatrixFunctions { pcomm->broadcast(&ck, 1, pcomm->root); } if (abs(qq) < conv_thrd + abs(eigvals[ck]) * abs(eigvals[ck]) * - rel_conv_thrd * rel_conv_thrd) { + rel_conv_thrd * rel_conv_thrd && + m >= k) { ck++; if (ck == k) break; diff --git a/src/core/spin_permutation.hpp b/src/core/spin_permutation.hpp index 16531f7b..6bdb3437 100644 --- a/src/core/spin_permutation.hpp +++ b/src/core/spin_permutation.hpp @@ -938,8 +938,9 @@ struct SpinPermPattern { vector mask; vector data; SpinPermPattern(uint16_t n, - const vector &mask = vector()) - : n(n), mask(mask), data(initialize(n, mask)) {} + const vector &mask = vector(), + int max_n_sites = 0) + : n(n), mask(mask), data(initialize(n, mask, max_n_sites)) {} static vector all_reordering(const vector &x, const vector &mask = vector()) { @@ -1007,13 +1008,16 @@ struct SpinPermPattern { return r; } static vector - initialize(uint16_t n, const vector &mask = vector()) { + initialize(uint16_t n, const vector &mask = vector(), + int max_n_sites = 0) { int mi = n; if (mask.size() != 0) { mi = 1; for (uint16_t j = 1; j < n; j++) mi += mask[j] != mask[j - 1]; } + if (max_n_sites != 0) + mi = mi < max_n_sites ? mi : max_n_sites; map, vector>> mp; for (uint16_t i = 0; i <= n; i++) mp[make_pair(0, i)] = vector>(); @@ -1190,12 +1194,14 @@ struct SpinPermScheme { SpinPermScheme() {} SpinPermScheme(string spin_str, bool su2 = true, bool is_fermion = true, bool is_npdm = false, bool is_drt = false, - const vector &mask = vector()) { + const vector &mask = vector(), + int max_n_sites = 0) { int nn = SpinPermRecoupling::count_cds(spin_str); SpinPermScheme r = su2 ? SpinPermScheme::initialize_su2(nn, spin_str, is_npdm, is_drt, - mask) - : SpinPermScheme::initialize_sz(nn, spin_str, is_fermion, mask); + mask, max_n_sites) + : SpinPermScheme::initialize_sz(nn, spin_str, is_fermion, mask, + max_n_sites); index_patterns = r.index_patterns; this->mask = r.mask; data = r.data; @@ -1204,10 +1210,11 @@ struct SpinPermScheme { } static SpinPermScheme initialize_sz(int nn, const string &spin_str, bool is_fermion = true, - const vector &mask = vector()) { + const vector &mask = vector(), + int max_n_sites = 0) { using T = SpinPermTensor; using R = SpinPermRecoupling; - SpinPermPattern spat(nn, mask); + SpinPermPattern spat(nn, mask, max_n_sites); vector mptr; SpinPermScheme r; r.index_patterns.resize(spat.count()); @@ -1241,10 +1248,11 @@ struct SpinPermScheme { static SpinPermScheme initialize_sany(int nn, const string &spin_str, const string &fermionic_ops = "cdCD", - const vector &mask = vector()) { + const vector &mask = vector(), + int max_n_sites = 0) { using T = SpinPermTensor; using R = SpinPermRecoupling; - SpinPermPattern spat(nn, mask); + SpinPermPattern spat(nn, mask, max_n_sites); vector mptr; SpinPermScheme r; r.index_patterns.resize(spat.count()); @@ -1463,7 +1471,8 @@ struct SpinPermScheme { static SpinPermScheme initialize_su2(int nn, const string &spin_str, bool is_npdm = false, bool is_drt = false, - const vector &mask = vector()) { + const vector &mask = vector(), + int max_n_sites = 0) { using T = SpinPermTensor; using R = SpinPermRecoupling; SU2CG cg; @@ -1473,7 +1482,7 @@ struct SpinPermScheme { string spin_pat_str = R::split_cds(spin_str, cds); bool heis = cds.size() != 0 && cds[0] == 2; int target_twos = R::get_target_twos(spin_pat_str); - SpinPermPattern spat(nn, mask); + SpinPermPattern spat(nn, mask, max_n_sites); SpinPermScheme r; r.index_patterns.resize(spat.count()); r.data.resize(spat.count()); @@ -1523,7 +1532,8 @@ struct SpinPermScheme { static SpinPermScheme initialize_su2_old2(int nn, string spin_str, bool is_npdm = false, bool is_drt = false, - const vector &mask = vector()) { + const vector &mask = vector(), + int max_n_sites = 0) { using T = SpinPermTensor; using R = SpinPermRecoupling; SU2CG cg; @@ -1533,7 +1543,7 @@ struct SpinPermScheme { spin_str = R::split_cds(spin_str, cds); bool heis = cds.size() != 0 && cds[0] == 2; int target_twos = R::get_target_twos(spin_str); - SpinPermPattern spat(nn, mask); + SpinPermPattern spat(nn, mask, max_n_sites); SpinPermScheme r; r.index_patterns.resize(spat.count()); r.data.resize(spat.count()); diff --git a/src/dmrg/mps.hpp b/src/dmrg/mps.hpp index c6e5753b..a3eec361 100644 --- a/src/dmrg/mps.hpp +++ b/src/dmrg/mps.hpp @@ -667,9 +667,9 @@ template struct MPSInfo { } ubond_t get_max_bond_dimension() const { total_bond_t max_bdim = 0; - for (int i = 0; i <= n_sites; i++) + for (int i = 0; i < n_sites; i++) max_bdim = max(left_dims[i]->n_states_total, max_bdim); - for (int i = n_sites; i >= 0; i--) + for (int i = n_sites; i > 0; i--) max_bdim = max(right_dims[i]->n_states_total, max_bdim); return (ubond_t)min((uint64_t)max_bdim, (uint64_t)numeric_limits::max()); @@ -2385,6 +2385,12 @@ template struct MPS { for (int i = 0; i < n_sites; i++) random_canonicalize_tensor(i); } + virtual void iscale(FL d) { + load_tensor(center); + tensors[center]->iscale(d); + save_tensor(center); + unload_tensor(center); + } virtual void set_inact_ext_identity(int n_inactive, int n_external) { for (int i = 0; i < n_inactive; i++) if (tensors[i] != nullptr && i < center) { diff --git a/src/dmrg/sweep_algorithm.hpp b/src/dmrg/sweep_algorithm.hpp index 0a45d78c..5e852e06 100644 --- a/src/dmrg/sweep_algorithm.hpp +++ b/src/dmrg/sweep_algorithm.hpp @@ -2548,8 +2548,9 @@ template struct DMRG { sweep_range.push_back(it); Timer t; + callback_()->compute("DMRG::sweep.start", iprint); for (auto i : sweep_range) { - callback_()->compute("DMRG::sweep", iprint); + callback_()->compute("DMRG::sweep::iter.start", iprint); check_signal_()(); if (iprint >= 2) { if (me->dot == 2) @@ -2614,7 +2615,9 @@ template struct DMRG { me->para_rule->comm->barrier(); } } + callback_()->compute("DMRG::sweep::iter.end", iprint); } + callback_()->compute("DMRG::sweep.end", iprint); size_t idx = min_element(sweep_energies.begin(), sweep_energies.end(), [](const vector &x, const vector &y) { diff --git a/src/pybind/pybind_core.hpp b/src/pybind/pybind_core.hpp index 6d61da3e..7fbfac23 100644 --- a/src/pybind/pybind_core.hpp +++ b/src/pybind/pybind_core.hpp @@ -874,6 +874,7 @@ template void bind_fl_sparse(py::module &m) { py::arg("length")) .def("trace", &SparseMatrix::trace) .def("norm", &SparseMatrix::norm) + .def("iscale", &SparseMatrix::iscale) .def("conjugate", &SparseMatrix::conjugate) .def("__getitem__", [](SparseMatrix *self, int idx) { return (*self)[idx]; }) @@ -2322,10 +2323,12 @@ template void bind_io(py::module &m) { .def_readwrite("data", &SpinPermPattern::data) .def(py::init()) .def(py::init &>()) + .def(py::init &, int>()) .def_static("all_reordering", &SpinPermPattern::all_reordering, py::arg("x"), py::arg("mask") = vector()) .def_static("initialize", &SpinPermPattern::initialize, py::arg("n"), - py::arg("mask") = vector()) + py::arg("mask") = vector(), + py::arg("max_n_sites") = 0) .def_static("get_unique", &SpinPermPattern::get_unique) .def_static("make_matrix", &SpinPermPattern::make_matrix) .def("count", &SpinPermPattern::count) @@ -2358,30 +2361,34 @@ template void bind_io(py::module &m) { .def(py::init()) .def(py::init &>()) + .def(py::init &, + int>()) .def_readwrite("index_patterns", &SpinPermScheme::index_patterns) .def_readwrite("data", &SpinPermScheme::data) .def_readwrite("is_su2", &SpinPermScheme::is_su2) .def_readwrite("left_vacuum", &SpinPermScheme::left_vacuum) .def_readwrite("mask", &SpinPermScheme::mask) - .def_static("initialize_sz", &SpinPermScheme::initialize_sz, - py::arg("nn"), py::arg("spin_str"), - py::arg("is_fermion") = true, - py::arg("mask") = vector()) - .def_static("initialize_sany", &SpinPermScheme::initialize_sany, - py::arg("nn"), py::arg("spin_str"), - py::arg("fermionic_ops") = string("cdCD"), - py::arg("mask") = vector()) + .def_static( + "initialize_sz", &SpinPermScheme::initialize_sz, py::arg("nn"), + py::arg("spin_str"), py::arg("is_fermion") = true, + py::arg("mask") = vector(), py::arg("max_n_sites") = 0) + .def_static( + "initialize_sany", &SpinPermScheme::initialize_sany, py::arg("nn"), + py::arg("spin_str"), py::arg("fermionic_ops") = string("cdCD"), + py::arg("mask") = vector(), py::arg("max_n_sites") = 0) .def_static("initialize_su2_old", &SpinPermScheme::initialize_su2_old, py::arg("nn"), py::arg("spin_str"), py::arg("is_npdm") = false) .def_static("initialize_su2", &SpinPermScheme::initialize_su2, py::arg("nn"), py::arg("spin_str"), py::arg("is_npdm") = false, py::arg("is_drt") = false, - py::arg("mask") = vector()) + py::arg("mask") = vector(), + py::arg("max_n_sites") = 0) .def_static("initialize_su2_old2", &SpinPermScheme::initialize_su2_old2, py::arg("nn"), py::arg("spin_str"), py::arg("is_npdm") = false, py::arg("is_drt") = false, - py::arg("mask") = vector()) + py::arg("mask") = vector(), + py::arg("max_n_sites") = 0) .def("to_str", &SpinPermScheme::to_str); py::bind_vector>>(m, diff --git a/src/pybind/pybind_dmrg.hpp b/src/pybind/pybind_dmrg.hpp index 16087d31..e9a6e672 100644 --- a/src/pybind/pybind_dmrg.hpp +++ b/src/pybind/pybind_dmrg.hpp @@ -408,6 +408,7 @@ template void bind_fl_mps(py::module &m) { .def("canonicalize", &MPS::canonicalize) .def("dynamic_canonicalize", &MPS::dynamic_canonicalize) .def("random_canonicalize", &MPS::random_canonicalize) + .def("iscale", &MPS::iscale) .def("set_inact_ext_identity", &MPS::set_inact_ext_identity) .def("from_singlet_embedding_wfn", &MPS::from_singlet_embedding_wfn, py::arg("cg"),