Open 페르몬+Psi4에서 H2분자의 기능 계산(엄격한 대각화)

지난번에서 진행된 제2량화 해밀토니안의 계수 계산도'Psi4과'PySCF의 양화 화학 계산 패키지를 통해 할 수 있다.
저번에 사용된 "OpenFermion"(참고논문: arXiv"는 이 가방과 연결을 통해 제2량화 해밀턴의 구성·Bravy-Kitaev 변환·기태의 결정(해밀턴턴 행렬의 엄격한 대각화)까지 단숨에 관통할 수 있다.
이번에는 Open Permion과 Psi4를 사용하십시오.
「Scalable Quantum Simulation of Molecular Energies」(PRX 2016)
( https://journals.aps.org/prx/abstract/10.1103/PhysRevX.6.031007 )
논문의 수치 계산 결과(H$2달러 분자의 총 에너지 곡면)를 재현하다.

할 일


• 설치 Psi4
• Open Fermon-Psi4 설치
・H$2달러 분자기 에너지 계산

Psi4 설치



공식 사이트downloads에서 설치 프로그램을 다운로드할 수 있습니다.

주의해야 할 것은 Mac 사용자가 어느 정도 유행이 지났다는 것이다모델의 경우 다음 OLD HDW를 선택해야 합니다Report problems with 1.1 installers.나는 이 설치 오류로 이틀 정도 사라졌어...터미널 실행psi4 --test 테스트 계산이 시작된 후 설치에 성공했습니다.위의 오류가 발생하면 Illegal Instruction 4와 같은 오류가 표시됩니다.

Open Permon-Psi4 설치


Open Fermon-Psi4라는 플러그인을 통해 Open Fermion과 Psi4를 연결합니다.
공식 GiitHub에 따라 설치했습니다.

Open Permon-Psi4의 실행


먼저 계산하려는 분자 시스템의 매개변수를 지정합니다.geometry 중의 분자 구조,basis의 기함수multiplicity는 전회전구 $S시 $2S+1달러(이번에는 싱글의 기초상태이기 때문에 $S=0달러)charge전하(전리가 없으면 $0$)description에 저장된 파일 이름
.
이 함수MolecularData를 하나의 데이터로 합친 데이터로 변수molecule에 전달한다.
from openfermion.hamiltonians import MolecularData

geometry = [["H", [0,0,0]],
           ["H", [0,0,0.7414]]]
basis = "sto-3g"
multiplicity = 1
charge = 0
description = "test" #str()

molecule = MolecularData(geometry, basis, multiplicity, charge, description)
여기서부터 Openfermon-psi 4를 통해 Psi4를 실행하여 계산 결과를 얻는다.run_psi4 이 함수로 Openfermion에서 Psi4를 실행할 수 있습니다.
from openfermionpsi4 import run_psi4
from openfermion.transforms import get_fermion_operator, jordan_wigner, bravyi_kitaev

molecule = run_psi4(molecule)

print(molecule.get_molecular_hamiltonian())

bk_hamiltonian = bravyi_kitaev(get_fermion_operator(molecule.get_molecular_hamiltonian()))
print(bk_hamiltonian)
molecule는 대상에서 실례를 지정하여 결과를 호출할 수 있다.
이 예에서 .get_molecular_hamiltonian()에 따라 페르미온 오퍼레이터의 Hamiltonian이 자동으로 구성된다.
또한, 지난번 진행된 브라비-Kitaev 변환을 계속하여 qubit operator의 Hamiltonian을 획득하였다.이전 결과와 거의 일치합니다. ($\mathrmI$의 계수는 일정한 수량 항목의 차이만 발생합니다.)
Output
() 0.713753990544915
((0, 1), (0, 0)) -1.252463571592775
((1, 1), (1, 0)) -1.252463571592775
((2, 1), (2, 0)) -0.4759487172683108
((3, 1), (3, 0)) -0.4759487172683108
((0, 1), (1, 1), (1, 0), (0, 0)) 0.33724438286695113
((0, 1), (1, 1), (3, 0), (2, 0)) 0.09064440419713071
((0, 1), (2, 1), (0, 0), (2, 0)) 0.09064440419713077
((0, 1), (2, 1), (2, 0), (0, 0)) 0.3317340479282188
((0, 1), (3, 1), (1, 0), (2, 0)) 0.09064440419713077
((0, 1), (3, 1), (3, 0), (0, 0)) 0.3317340479282188
((1, 1), (0, 1), (0, 0), (1, 0)) 0.33724438286695113
((1, 1), (0, 1), (2, 0), (3, 0)) 0.09064440419713071
((1, 1), (2, 1), (0, 0), (3, 0)) 0.09064440419713077
((1, 1), (2, 1), (2, 0), (1, 0)) 0.3317340479282188
((1, 1), (3, 1), (1, 0), (3, 0)) 0.09064440419713077
((1, 1), (3, 1), (3, 0), (1, 0)) 0.3317340479282188
((2, 1), (0, 1), (0, 0), (2, 0)) 0.33173404792821903
((2, 1), (0, 1), (2, 0), (0, 0)) 0.0906444041971309
((2, 1), (1, 1), (1, 0), (2, 0)) 0.33173404792821903
((2, 1), (1, 1), (3, 0), (0, 0)) 0.0906444041971309
((2, 1), (3, 1), (1, 0), (0, 0)) 0.09064440419713096
((2, 1), (3, 1), (3, 0), (2, 0)) 0.34869688341114197
((3, 1), (0, 1), (0, 0), (3, 0)) 0.33173404792821903
((3, 1), (0, 1), (2, 0), (1, 0)) 0.0906444041971309
((3, 1), (1, 1), (1, 0), (3, 0)) 0.33173404792821903
((3, 1), (1, 1), (3, 0), (1, 0)) 0.0906444041971309
((3, 1), (2, 1), (0, 0), (1, 0)) 0.09064440419713096
((3, 1), (2, 1), (2, 0), (3, 0)) 0.34869688341114197

(-0.09886397351781719+0j) [] +
(0.17119774853325845+0j) [Z0] +
(0.17119774853325845+0j) [Z0 Z1] +
(-0.22278592890106907+0j) [Z2] +
(-0.22278592890106913+0j) [Z1 Z2 Z3] +
(0.16862219143347557+0j) [Z1] +
(0.04532220209856542+0j) [Y0 Z1 Y2 Z3] +
(0.04532220209856542+0j) [X0 Z1 X2] +
(0.04532220209856542+0j) [X0 Z1 X2 Z3] +
(0.04532220209856542+0j) [Y0 Z1 Y2] +
(0.12054482186554402+0j) [Z0 Z2] +
(0.16586702396410946+0j) [Z0 Z1 Z2 Z3] +
(0.16586702396410946+0j) [Z0 Z1 Z2] +
(0.12054482186554402+0j) [Z0 Z2 Z3] +
(0.17434844170557098+0j) [Z1 Z3]
오픈 페르미온에서는 큐빅맵의 해밀턴니언을 희소 행렬 표시로 자동 번역해 대각화에서 기초 에너지를 도출하기도 한다.
from openfermion.transforms import get_sparse_operator
from openfermion.utils import get_ground_state

sparse_operator = get_sparse_operator(bk_hamiltonian)
print(sparse_operator, "\n")
print(get_ground_state(sparse_operator)[0])
output
  (0, 0)    (0.7137539905449151+0j)
  (1, 1)    (0.23780527327660436+0j)
  (2, 2)    (0.45925032283057743+0j)
  (8, 2)    (0.18128880839426167+0j)
  (3, 3)    (0.23780527327660425+0j)
  (4, 4)    (-0.5324790108539945+0j)
  (5, 5)    (-0.5387095810478599+0j)
  (6, 6)    (-0.35119020245973287+0j)
  (12, 6)   (-0.18128880839426167+0j)
  (7, 7)    (0.3524341345564165+0j)
  (2, 8)    (0.18128880839426167+0j)
  (8, 8)    (-1.1166843869067329+0j)
  (9, 9)    (-0.4469857208564294+0j)
  (10, 10)  (0.9201067120161576+0j)
  (11, 11)  (-0.4469857208564296+0j)
  (6, 12)   (-0.18128880839426167+0j)
  (12, 12)  (-0.35119020245973276+0j)
  (13, 13)  (-0.5387095810478599+0j)
  (14, 14)  (-0.5324790108539946+0j)
  (15, 15)  (0.3524341345564164+0j) 

-1.137270174625323

H2분자의 에너지 곡면


지금까지의 코드를 모아 키의 장진을 계산하면 에너지 곡면을 쓸 수 있다.
from openfermion.hamiltonians import MolecularData
from openfermionpsi4 import run_psi4
from openfermion.transforms import get_fermion_operator, jordan_wigner, bravyi_kitaev, get_sparse_operator
from openfermion.utils import get_ground_state
import matplotlib.pyplot as plt
%matplotlib inline

def get_Energy(bond_length):
    geometry = [["H", [0,0,0]], ["H", [0,0,bond_length]]]
    basis = "sto-3g"
    multiplicity = 1
    charge = 0
    description = str(round(bond_length, 2))
    molecule = MolecularData(geometry, basis, multiplicity, charge, description)

    # run Psi4
    molecule = run_psi4(molecule) #, run_mp2 = True, run_cisd = True, run_ccsd = True, run_fci = True)

    bk_hamiltonian = bravyi_kitaev(get_fermion_operator(molecule.get_molecular_hamiltonian()))
    sparse_operator = get_sparse_operator(bk_hamiltonian)
    return get_ground_state(sparse_operator)[0]

initial = 0.20
step = 0.025
number = 28*4+1
data1 = []
data2 = []
for i in range(number):
    bond_length = initial + i*step 
    data1.append(bond_length)
    temp = get_Energy(bond_length)
    data2.append(temp)
    #print(bond_length, temp)

# 図にプロット
plt.plot(data1,data2,"blue")
plt.xlabel("R (Å)")
plt.ylabel("Ground Energy (hartree)")
plt.xlim(0.20,3.00)
plt.ylim(-1.2,0.2)
plt.legend()
plt.show

논문도와 대체로 일치한다!

좋은 웹페이지 즐겨찾기