From 6e5a28c4b4fb3707f9244fade7cbfe2cd878fd91 Mon Sep 17 00:00:00 2001 From: Xing Zhang Date: Wed, 18 Oct 2023 23:43:53 -0700 Subject: [PATCH] Allow to turn off AO symmetry for PBC KS calculations (#1905) * allow turning off AO symmetry for PBC DFT * add test --- examples/pbc/20-k_points_scf_ksymm.py | 6 ++++++ pyscf/pbc/dft/krks_ksymm.py | 5 +++-- pyscf/pbc/dft/krkspu.py | 4 ++-- pyscf/pbc/dft/krkspu_ksymm.py | 4 ++-- pyscf/pbc/dft/kuks_ksymm.py | 5 +++-- pyscf/pbc/dft/kukspu.py | 4 ++-- pyscf/pbc/dft/kukspu_ksymm.py | 4 ++-- pyscf/pbc/dft/test/test_krks_ksym.py | 12 ++++++++++++ pyscf/pbc/scf/test/test_khf_ksym.py | 9 +++++---- 9 files changed, 37 insertions(+), 16 deletions(-) diff --git a/examples/pbc/20-k_points_scf_ksymm.py b/examples/pbc/20-k_points_scf_ksymm.py index b738e66d02..2e61eee4e7 100644 --- a/examples/pbc/20-k_points_scf_ksymm.py +++ b/examples/pbc/20-k_points_scf_ksymm.py @@ -35,6 +35,12 @@ kmf.xc = 'camb3lyp' kmf.kernel() +# By default, the mean-field calculation will use symmetry-adapted +# crystalline orbitals whenever possible. This can be turned off manually +# when instantiating the mean-field object. +kmf = scf.KRHF(cell, kpts, use_ao_symmetry=False) +kmf.kernel() + # # The mean-field object with k-point symmetry can be converted back to # the correponding non-symmetric mean-field object diff --git a/pyscf/pbc/dft/krks_ksymm.py b/pyscf/pbc/dft/krks_ksymm.py index 6a2afd39c7..087c0241f1 100644 --- a/pyscf/pbc/dft/krks_ksymm.py +++ b/pyscf/pbc/dft/krks_ksymm.py @@ -151,8 +151,9 @@ class KsymAdaptedKRKS(krks.KRKS, khf_ksymm.KRHF): get_init_guess = khf_ksymm.KRHF.get_init_guess def __init__(self, cell, kpts=libkpts.KPoints(), xc='LDA,VWN', - exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald')): - khf_ksymm.KRHF.__init__(self, cell, kpts, exxdiv=exxdiv) + exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), + **kwargs): + khf_ksymm.KRHF.__init__(self, cell, kpts, exxdiv=exxdiv, **kwargs) rks.KohnShamDFT.__init__(self, xc) def dump_flags(self, verbose=None): diff --git a/pyscf/pbc/dft/krkspu.py b/pyscf/pbc/dft/krkspu.py index eebf4ad545..5cb550ce76 100644 --- a/pyscf/pbc/dft/krkspu.py +++ b/pyscf/pbc/dft/krkspu.py @@ -247,7 +247,7 @@ class KRKSpU(krks.KRKS): def __init__(self, cell, kpts=np.zeros((1,3)), xc='LDA,VWN', exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), - U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO'): + U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO', **kwargs): """ DFT+U args: U_idx: can be @@ -264,7 +264,7 @@ def __init__(self, cell, kpts=np.zeros((1,3)), xc='LDA,VWN', string, in 'minao'. minao_ref: reference for minao orbitals, default is 'MINAO'. """ - super(self.__class__, self).__init__(cell, kpts, xc=xc, exxdiv=exxdiv) + super(self.__class__, self).__init__(cell, kpts, xc=xc, exxdiv=exxdiv, **kwargs) set_U(self, U_idx, U_val) diff --git a/pyscf/pbc/dft/krkspu_ksymm.py b/pyscf/pbc/dft/krkspu_ksymm.py index a1ad5ca219..5ed432b5be 100644 --- a/pyscf/pbc/dft/krkspu_ksymm.py +++ b/pyscf/pbc/dft/krkspu_ksymm.py @@ -32,10 +32,10 @@ class KsymAdaptedKRKSpU(krks_ksymm.KRKS): @lib.with_doc(krkspu.KRKSpU.__init__.__doc__) def __init__(self, cell, kpts=libkpts.KPoints(), xc='LDA,VWN', exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), - U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO'): + U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO', **kwargs): krkspu.KRKSpU.__init__(self, cell, kpts=kpts, xc=xc, exxdiv=exxdiv, U_idx=U_idx, U_val=U_val, C_ao_lo=C_ao_lo, - minao_ref=minao_ref) + minao_ref=minao_ref, **kwargs) KRKSpU = KsymAdaptedKRKSpU diff --git a/pyscf/pbc/dft/kuks_ksymm.py b/pyscf/pbc/dft/kuks_ksymm.py index fbbf486a17..465b2943fb 100644 --- a/pyscf/pbc/dft/kuks_ksymm.py +++ b/pyscf/pbc/dft/kuks_ksymm.py @@ -147,8 +147,9 @@ class KsymAdaptedKUKS(kuks.KUKS, kuhf_ksymm.KUHF): _finalize = kuhf_ksymm.KUHF._finalize def __init__(self, cell, kpts=libkpts.KPoints(), xc='LDA,VWN', - exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald')): - kuhf_ksymm.KUHF.__init__(self, cell, kpts, exxdiv=exxdiv) + exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), + **kwargs): + kuhf_ksymm.KUHF.__init__(self, cell, kpts, exxdiv=exxdiv, **kwargs) rks.KohnShamDFT.__init__(self, xc) def dump_flags(self, verbose=None): diff --git a/pyscf/pbc/dft/kukspu.py b/pyscf/pbc/dft/kukspu.py index 9b88160238..6deb27590d 100644 --- a/pyscf/pbc/dft/kukspu.py +++ b/pyscf/pbc/dft/kukspu.py @@ -133,7 +133,7 @@ class KUKSpU(kuks.KUKS): def __init__(self, cell, kpts=np.zeros((1,3)), xc='LDA,VWN', exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), - U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO'): + U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO', **kwargs): """ DFT+U args: U_idx: can be @@ -150,7 +150,7 @@ def __init__(self, cell, kpts=np.zeros((1,3)), xc='LDA,VWN', string, in 'minao'. minao_ref: reference for minao orbitals, default is 'MINAO'. """ - super(self.__class__, self).__init__(cell, kpts, xc=xc, exxdiv=exxdiv) + super(self.__class__, self).__init__(cell, kpts, xc=xc, exxdiv=exxdiv, **kwargs) set_U(self, U_idx, U_val) diff --git a/pyscf/pbc/dft/kukspu_ksymm.py b/pyscf/pbc/dft/kukspu_ksymm.py index ecea076ca9..9ce89eb8e3 100644 --- a/pyscf/pbc/dft/kukspu_ksymm.py +++ b/pyscf/pbc/dft/kukspu_ksymm.py @@ -32,10 +32,10 @@ class KsymAdaptedKUKSpU(kuks_ksymm.KUKS): @lib.with_doc(kukspu.KUKSpU.__init__.__doc__) def __init__(self, cell, kpts=libkpts.KPoints(), xc='LDA,VWN', exxdiv=getattr(__config__, 'pbc_scf_SCF_exxdiv', 'ewald'), - U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO'): + U_idx=[], U_val=[], C_ao_lo='minao', minao_ref='MINAO', **kwargs): kukspu.KUKSpU.__init__(self, cell, kpts=kpts, xc=xc, exxdiv=exxdiv, U_idx=U_idx, U_val=U_val, C_ao_lo=C_ao_lo, - minao_ref=minao_ref) + minao_ref=minao_ref, **kwargs) KUKSpU = KsymAdaptedKUKSpU diff --git a/pyscf/pbc/dft/test/test_krks_ksym.py b/pyscf/pbc/dft/test/test_krks_ksym.py index 2673868513..d8977722d6 100644 --- a/pyscf/pbc/dft/test/test_krks_ksym.py +++ b/pyscf/pbc/dft/test/test_krks_ksym.py @@ -116,6 +116,18 @@ def test_kuks_monkhorst(self): kumf.kernel() self.assertAlmostEqual(kumf.e_tot, kumf0.e_tot, 6) + def test_krks_symorb(self): + cell1 = cell.copy() + cell1.build(symmorphic=True) + kpts = cell1.make_kpts([2,2,2], with_gamma_point=True,space_group_symmetry=True) + kmf = pscf.KRKS(cell1, kpts=kpts).run() + kmf1 = pscf.KRKS(cell1, kpts=kpts, use_ao_symmetry=False).run() + self.assertAlmostEqual(kmf.e_tot, kmf1.e_tot, 7) + assert abs(kmf.mo_coeff[0].orbsym - np.asarray([0, 4, 4, 4, 4, 4, 4, 0])).sum() == 0 + assert abs(kmf.mo_coeff[1].orbsym - np.asarray([0, 3, 4, 4, 0, 3, 4, 4])).sum() == 0 + assert abs(kmf.mo_coeff[2].orbsym - np.asarray([0, 0, 2, 2, 0, 2, 2, 0])).sum() == 0 + assert getattr(kmf1.mo_coeff[0], 'orbsym', None) is None + def test_rsh(self): kpts0 = He.make_kpts(nk, with_gamma_point=False) kmf0 = krks.KRKS(He, kpts=kpts0) diff --git a/pyscf/pbc/scf/test/test_khf_ksym.py b/pyscf/pbc/scf/test/test_khf_ksym.py index 6fbd746af1..5870dd1d34 100644 --- a/pyscf/pbc/scf/test/test_khf_ksym.py +++ b/pyscf/pbc/scf/test/test_khf_ksym.py @@ -87,11 +87,12 @@ def test_krhf_symorb(self): cell1.build(symmorphic=True) kpts = cell1.make_kpts([2,2,2], with_gamma_point=True,space_group_symmetry=True) kmf = pscf.KRHF(cell1, kpts=kpts).run() - kmf1 = pscf.KRHF(cell1, kpts=kpts, use_ao_symmetry=True).run() + kmf1 = pscf.KRHF(cell1, kpts=kpts, use_ao_symmetry=False).run() self.assertAlmostEqual(kmf.e_tot, kmf1.e_tot, 7) - assert abs(kmf1.mo_coeff[0].orbsym - np.asarray([0, 4, 4, 4, 4, 4, 4, 0])).sum() == 0 - assert abs(kmf1.mo_coeff[1].orbsym - np.asarray([0, 3, 4, 4, 0, 3, 4, 4])).sum() == 0 - assert abs(kmf1.mo_coeff[2].orbsym - np.asarray([0, 0, 2, 2, 0, 2, 2, 0])).sum() == 0 + assert abs(kmf.mo_coeff[0].orbsym - np.asarray([0, 4, 4, 4, 4, 4, 4, 0])).sum() == 0 + assert abs(kmf.mo_coeff[1].orbsym - np.asarray([0, 3, 4, 4, 0, 3, 4, 4])).sum() == 0 + assert abs(kmf.mo_coeff[2].orbsym - np.asarray([0, 0, 2, 2, 0, 2, 2, 0])).sum() == 0 + assert getattr(kmf1.mo_coeff[0], 'orbsym', None) is None def test_kuhf_gamma_center(self): self.assertAlmostEqual(kumf_ksymm.e_tot, kumf0.e_tot, 7)