1#!/usr/bin/env python
2#
3# Author: Qiming Sun <osirpt.sun@gmail.com>
4#
5
6'''
7Control the SCF procedure by different initial guess.
8
9Spherical symmetry needs to be carefully treated in the atomic calculation.
10The default initial guess may break the spherical symmetry.  Proper initial
11guess can help to overcome the symmetry broken issue. It is often needed when
12computing the open-shell atomic HF ground state.
13
14See also 32-v_atom_rohf.py
15'''
16
17import numpy
18from pyscf import gto
19from pyscf import scf
20
21mol = gto.Mole()
22mol.build(
23    verbose = 5,
24    output = None,
25    symmetry = 'D2h',
26    atom = [['Cr',(0, 0, 0)], ],
27    basis = 'cc-pvdz',
28    charge = 6,
29    spin = 0,
30)
31mf = scf.RHF(mol)
32mf.kernel()
33#
34# use cation to produce initial guess
35#
36dm1 = mf.make_rdm1()
37
38mol.charge = 0
39mol.spin = 6
40mol.build(False,False)
41
42mf = scf.RHF(mol)
43mf.chkfile = 'cr_atom.chk'
44# 'Ag':(6,3) means to assign 6 alpha electrons and 3 beta electrons to irrep Ag
45mf.irrep_nelec = {'Ag': (6,3), 'B1g': (1,0), 'B2g': (1,0), 'B3g': (1,0)}
46mf.kernel(dm0=dm1)
47# The output of .analyze() method can help to identify whether the spherical
48# symmetry is conserved.
49#mf.analyze()
50
51
52#
53# Use the converged small-basis ROHF to produce initial guess for large basis
54#
55mol.basis = 'aug-cc-pvdz'
56mol.build(False, False)
57mf = scf.RHF(mol)
58mf.level_shift = .2
59mf.irrep_nelec = {'Ag': (6,3), 'B1g': (1,0), 'B2g': (1,0), 'B3g': (1,0)}
60# init guess can be read from chkfile
61dm = mf.from_chk('cr_atom.chk')
62mf.kernel(dm)
63
64
65#
66# Another choice to conduct a large basis calculation from small basis resutls
67# is to use second order SCF solver (.newton method).  Based on the initial
68# guess from the small basis calculation which has proper spherical symmetry,
69# SOSCF solver often provides reliable results that reserve the spherical
70# symmetry.
71#
72mf1 = scf.RHF(mol).newton()
73dm = mf1.from_chk('cr_atom.chk')
74mf1.kernel(dm)
75
76
77#
78# UHF is another way to produce initial guess
79#
80charge = 0
81spin = 6
82mol.basis = 'aug-cc-pvdz'
83mol.build(False,False)
84
85mf = scf.UHF(mol)
86mf.irrep_nelec = {'Ag': (6,3), 'B1g': (1,0), 'B2g': (1,0), 'B3g': (1,0)}
87mf.kernel()
88dm1 = mf.make_rdm1()
89
90mf = scf.ROHF(mol)
91mf.irrep_nelec = {'Ag': (6,3), 'B1g': (1,0), 'B2g': (1,0), 'B3g': (1,0)}
92mf.kernel(dm1)
93
94
95#
96# The third way to force the calculation strictly following the correct
97# configurations is the second order SCF optimizaiton.  In the following code,
98# we call a calculation on cation for a correct HF configuration with spherical
99# symmetry.  This HF configuration is next pass to second order SCF solver
100# (.newton method) to solve X2C-ROHF model of the open shell atom.
101#
102mol = gto.M(
103    verbose = 4,
104    symmetry = True,
105    atom = [['Cr',(0, 0, 0)], ],
106    basis = 'cc-pvdz-dk',
107    charge = 6,
108    spin = 0)
109mf = scf.RHF(mol).x2c().run()
110mo, mo_occ = mf.mo_coeff, mf.mo_occ
111
112mol.charge = 0
113mol.spin = 6
114mol.build(False,False)
115
116mf = scf.RHF(mol).x2c().newton()
117mo_occ[9:15] = 1
118mf.kernel(mo, mo_occ)
119#mf.analyze()
120
121