Skip to content

Commit d5a5080

Browse files
committed
examples: add N2 state-averaged GASSCF comparison
1 parent a983975 commit d5a5080

2 files changed

Lines changed: 122 additions & 0 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/env python
2+
#
3+
# Author: Yi Deng <yideng@uchicago.edu>
4+
#
5+
6+
"""Three-state-averaged triplet N2 GASSCF, compared with OpenMolcas."""
7+
8+
from pathlib import Path
9+
10+
import numpy
11+
12+
from pyscf import gto, scf
13+
from pyscf.mcscf import gasscf
14+
15+
16+
# OpenMolcas reference input:
17+
#
18+
# &GATEWAY
19+
# ... (Geometry and basis are stored in the .npz file)
20+
# noCD
21+
#
22+
# &SEWARD
23+
#
24+
# &RASSCF
25+
#
26+
# LUMORB
27+
# FILEORB = n2_guessorb.INPORB
28+
#
29+
# Spin = 3
30+
# Symmetry = 1
31+
#
32+
# Nactel = 10 0 0
33+
# Inactive = 2
34+
#
35+
# GASSCF
36+
# 3
37+
# 2
38+
# 2 4
39+
# 4
40+
# 7 9
41+
# 2
42+
# 10 10
43+
#
44+
# CIRoot = 3 3 1
45+
# ITERations = 200 100
46+
# CIMX = 200
47+
#
48+
# OpenMolcas output:
49+
#
50+
# :: RASSCF root number 1 Total energy: -108.82664198
51+
# :: RASSCF root number 2 Total energy: -108.80517976
52+
# :: RASSCF root number 3 Total energy: -108.80517974
53+
#
54+
55+
openmolcas_energies = numpy.array([
56+
-108.82664198, -108.80517976, -108.80517974,
57+
])
58+
weights = (1/3, 1/3, 1/3)
59+
60+
here = Path(__file__).resolve().parent
61+
with numpy.load(here / "data/n2_sa_mo.npz", allow_pickle=False) as data:
62+
mol = gto.loads(data["mol"].item())
63+
mo_coeff = data["mo_coeff"]
64+
65+
mol.max_memory = 8000 # MB
66+
mol.verbose = 4
67+
68+
# One-cycle ROHF for mf generation.
69+
mf = scf.ROHF(mol)
70+
mf.max_cycle = 1
71+
mf.kernel()
72+
mf.mo_coeff = mo_coeff
73+
74+
# GASSCF(10e,8o), with three GAS spaces containing 2, 4, and 2 orbitals.
75+
mc = gasscf.GASSCF(
76+
mf,
77+
ncas=8,
78+
nelecas=(6,4),
79+
ncore=2,
80+
gas_orbs=(2,4,2),
81+
gas_restr=((2,4),(7,9),(10,10)),
82+
gas_restr_type="cumulative-occ",
83+
).state_average_(weights)
84+
85+
mc.verbose = 4
86+
mc.max_cycle_macro = 80
87+
mc.conv_tol = 1e-9
88+
mc.conv_tol_grad = 1e-5
89+
mc.fcisolver.max_cycle = 300
90+
mc.fcisolver.max_space = 40
91+
mc.fcisolver.conv_tol = 1e-11
92+
mc.fcisolver.conv_tol_residual = 1e-7
93+
mc.kernel(mo_coeff)
94+
95+
energies = numpy.asarray(mc.e_states)
96+
ss, _ = mc.fcisolver.states_spin_square(mc.ci, mc.ncas, mc.nelecas)
97+
reference_average = numpy.dot(weights, openmolcas_energies)
98+
99+
print()
100+
print("OpenMolcas/PySCF triplet N2 SA3 GASSCF comparison")
101+
print("Root Weight E(OpenMolcas) / Eh E(PySCF) / Eh diff / Eh <S^2>")
102+
for i, (weight, ref, energy, spin2) in enumerate(
103+
zip(weights, openmolcas_energies, energies, ss), start=1):
104+
print(f"{i:4d} {weight:.6f} {ref:20.12f} {energy:20.12f} "
105+
f"{energy - ref:+.3e} {spin2:10.7f}")
106+
print(f"SA energy (OpenMolcas) / Eh: {reference_average:.12f}")
107+
print(f"SA energy (PySCF) / Eh : {mc.e_tot:.12f}")
108+
print(f"SA difference / Eh : {mc.e_tot - reference_average:+.3e}")
109+
print(f"GASSCF converged : {mc.converged}")
110+
111+
# Example output (last digits may depend on platform):
112+
#
113+
# OpenMolcas/PySCF triplet N2 SA3 GASSCF comparison
114+
# Root Weight E(OpenMolcas) / Eh E(PySCF) / Eh diff / Eh <S^2>
115+
# 1 0.333333 -108.826641980000 -108.826641866414 +1.136e-07 2.0000000
116+
# 2 0.333333 -108.805179760000 -108.805179818961 -5.896e-08 2.0000000
117+
# 3 0.333333 -108.805179740000 -108.805179812524 -7.252e-08 2.0000000
118+
# SA energy (OpenMolcas) / Eh: -108.812333826667
119+
# SA energy (PySCF) / Eh : -108.812333832633
120+
# SA difference / Eh : -5.966e-09
121+
# GASSCF converged : True
122+
29.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)