Skip to content

Commit fb406f7

Browse files
committed
Add examples for ASE interface (fix pyscf#624)
1 parent ede68dc commit fb406f7

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

examples/geomopt/01-ase.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python
2+
3+
'''
4+
Geometry optimization with ASE
5+
6+
ASE uses the BFGS optimizer by default. This general-purpose algorithm is often
7+
not as efficient as dedicated geometry optimizers such as Berny or geomeTRIC.
8+
'''
9+
10+
import pyscf
11+
12+
mol = pyscf.M(atom='N 0 0 0; N 0 0 1.2', basis='ccpvdz')
13+
mf_opt = mol.RHF().Gradients().optimizer(solver='ase')
14+
15+
mol_eq = mf_opt.kernel()
16+
print(mol_eq.tostring())
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python
2+
3+
import pyscf
4+
from pyscf.pbc.tools.pyscf_ase import PySCF, cell_from_ase
5+
from ase.build import bulk
6+
from ase.optimize import BFGS
7+
from ase.filters import UnitCellFilter, StrainFilter
8+
9+
atoms = bulk('Si', 'diamond', a=5.43)
10+
# Only .atoms and .a are defined in this cell instance. It's necessary to assign
11+
# basis set and pseudo potential
12+
cell = cell_from_ase(atoms)
13+
cell.basis = 'gth-dzvp'
14+
cell.pseudo = 'gth-pade'
15+
16+
kmesh = [2, 2, 2]
17+
kpts = cell.make_kpts(kmesh)
18+
# Create a PySCF method, which will be used as a template in the following ASE
19+
# calculator. Parameters (such as convergence tol) can be defined in the
20+
# template.
21+
mf = cell.KRKS(xc='pbe', kpts=kpts)
22+
mf.conv_tol = 1e-6
23+
24+
# PySCF(method=...) creates an ASE calculator for the specified PySCF method.
25+
# All methods implemented in PySCF can be used as templates to create a Calculator.
26+
# However, some methods may not support gradients or stress tensors. Geometry
27+
# optimization or lattice optimization that rely on these functionalities will
28+
# be halted.
29+
atoms.calc = PySCF(method=mf)
30+
31+
# optimize atom positions
32+
opt = BFGS(atoms, logfile='atom_pos.log')
33+
opt.run()
34+
print(atoms.get_positions())
35+
36+
37+
# Optimize both lattice and atom positions
38+
opt = BFGS(UnitCellFilter(atoms), logfile='lattice_atom.log')
39+
opt.run()
40+
print(atoms.get_positions())
41+
print(atoms.cell)
42+
43+
44+
# Optimize lattice only. Atom positions (fractional coordinates) are frozen.
45+
opt = BFGS(StrainFilter(atoms), logfile='lattice_atom.log')
46+
opt.run()
47+
print(atoms.cell)

examples/pbc/09-talk_to_ase.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
mf_dict = { 'xc' : 'lda,vwn' }
3939

4040
# Once this is setup, ASE is used for everything from this point on
41-
ase_atom.set_calculator(pyscf_ase.PySCF(molcell=cell, mf_class=mf_class, mf_dict=mf_dict))
41+
ase_atom.calc = pyscf_ase.PySCF(method=mf)
4242

4343
print("ASE energy", ase_atom.get_potential_energy())
4444
print("ASE energy (should avoid re-evaluation)", ase_atom.get_potential_energy())
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env python
2+
3+
'''
4+
Using PySCF as an ASE Calculator
5+
6+
Any PySCF mean-field or post-mean-field method (e.g., DFT, HF, CCSD) can be
7+
wrapped as an ASE-compatible calculator using the pyscf_ase interface.
8+
9+
More examples can be found in examples/pbc/09-ase_geometry_optimization.py and
10+
examples/pbc/09-talk_to_ase.py
11+
'''
12+
13+
import pyscf
14+
from pyscf.pbc.tools.pyscf_ase import PySCF, ase_atoms_to_pyscf
15+
from ase import Atoms
16+
17+
# Define molecules using ase.Atoms class, the ase_atoms_to_pyscf function can
18+
# convert the geometry to pyscf input format
19+
atoms = Atoms('N2', [(0, 0, 0), (0, 0, 1.2)])
20+
mol = pyscf.M(atom=ase_atoms_to_pyscf(atoms), basis='ccpvdz')
21+
22+
# Example 1: Use a DFT method as an ASE calculator
23+
mf = mol.RKS(xc='pbe0')
24+
atoms.calc = PySCF(method=mf)
25+
26+
# Example 2: Use a post-HF method (CCSD) as an ASE calculator
27+
atoms.calc = PySCF(method=mol.RHF().CCSD())

pyscf/pbc/tools/pyscf_ase.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def cell_from_ase(ase_atoms):
7272

7373
class PySCF(Calculator):
7474
implemented_properties = ['energy', 'forces', 'stress',
75-
'dipole', 'magmom']
75+
'dipole', 'magmom', 'polarizability']
7676

7777
default_parameters = {}
7878

@@ -169,6 +169,20 @@ def calculate(self, atoms=None, properties=['energy'],
169169
# in Gaussian cgs unit
170170
self.results['dipole'] = base_method.dip_moment() * Debye
171171

172+
if 'polarizability' in properties:
173+
assert hasattr(base_method, 'istype') and base_method.istype('SCF'), \
174+
'Polarizability can only be computed with mean-field methods'
175+
if self.pbc:
176+
from pyscf.pbc.prop.polarizability.rhf import Polarizability
177+
p = Polarizability(base_method).polarizability()
178+
else:
179+
from pyscf.prop.polarizability import rhf, uhf
180+
if base_method.istype('UHF'):
181+
p = uhf.Polarizability(base_method).polarizability()
182+
else:
183+
p = rhf.Polarizability(base_method).polarizability()
184+
self.results['polarizability'] = p * (BOHR**3)
185+
172186
if 'magmom' in properties:
173187
magmom = self.mol.spin
174188
self.results['magmom'] = magmom

0 commit comments

Comments
 (0)