def test_detect_symm_c2h(self): atoms = [['H' , (1., 0., 2.)], ['He', (0., 1., 0.)], ['H' , (1., 0., 0.)], ['H' , (-1.,0., 0.)], ['H' , (-1.,0.,-2.)], ['He', (0.,-1., 0.)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'C2h') self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0,4],[1,5],[2,3]]) self.assertTrue(geom.check_given_symm('C2h', atoms)) atoms = [['H' , (1., 0., 1.)], ['H' , (1., 0.,-1.)], ['He', (0., 0., 2.)], ['He', (2., 0.,-2.)], ['Li', (1., 1., 0.)], ['Li', (1.,-1., 0.)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'C2h') self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0, 1], [2, 3], [4, 5]]) self.assertTrue(geom.check_given_symm('C2h', atoms))
def test_d5h(self): atoms = ringhat(5, u) atoms = atoms[5:] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D5h') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2v') self.assertTrue(geom.check_given_symm('C2v', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 4], [2, 3], [5, 6]]) atoms = ringhat(5, u) atoms = atoms[5:] atoms[1][0] = 'C1' gpname, orig, axes = geom.detect_symm(atoms, { 'C': 'ccpvdz', 'C1': 'sto3g', 'N': '631g' }) self.assertEqual(gpname, 'C2v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2v') self.assertTrue(geom.check_given_symm('C2v', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 2], [1], [3, 4], [5, 6]])
def test_d5h(self): atoms = ringhat(5, u) atoms = atoms[5:] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D5h') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2v') self.assertTrue(geom.check_given_symm('C2v', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 4], [2, 3], [5, 6]]) atoms = ringhat(5, u) atoms = atoms[5:] atoms[1][0] = 'C1' gpname, orig, axes = geom.detect_symm(atoms, {'C':'ccpvdz','C1':'sto3g','N':'631g'}) self.assertEqual(gpname, 'C2v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2v') self.assertTrue(geom.check_given_symm('C2v', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0,2],[1],[3,4],[5,6]])
def test_Coov(self): atoms = [['H', (0,0,0)], ['H', (0,0,-1)], ['H1', (0,0,1)]] basis = {'H':'sto3g', 'H1':'6-31g'} gpname, orig, axes = geom.detect_symm(atoms, basis) self.assertEqual(gpname, 'Coov') self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1] ,[2]]) gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Coov') self.assertTrue(geom.check_given_symm('Coov', atoms, basis)) self.assertTrue(geom.check_given_symm('C2v', atoms, basis)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1], [2]])
def test_Coov(self): atoms = [['H', (0, 0, 0)], ['H', (0, 0, -1)], ['H1', (0, 0, 1)]] basis = {'H': 'sto3g', 'H1': '6-31g'} gpname, orig, axes = geom.detect_symm(atoms, basis) self.assertEqual(gpname, 'Coov') self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1], [2]]) gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Coov') self.assertTrue(geom.check_given_symm('Coov', atoms, basis)) self.assertTrue(geom.check_given_symm('C2v', atoms, basis)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1], [2]])
def test_t(self): atoms = [['C', ( 1.0 ,-1.0 , 1.0 )], ['O', ( 1.0-.1,-1.0+.2, 1.0 )], ['O', ( 1.0 ,-1.0+.1, 1.0-.2)], ['O', ( 1.0-.2,-1.0 , 1.0-.1)], ['C', (-1.0 , 1.0 , 1.0 )], ['O', (-1.0+.1, 1.0-.2, 1.0 )], ['O', (-1.0 , 1.0-.1, 1.0-.2)], ['O', (-1.0+.2, 1.0 , 1.0-.1)], ['C', ( 1.0 , 1.0 ,-1.0 )], ['O', ( 1.0-.2, 1.0 ,-1.0+.1)], ['O', ( 1.0 , 1.0-.1,-1.0+.2)], ['O', ( 1.0-.1, 1.0-.2,-1.0 )], ['C', (-1.0 ,-1.0 ,-1.0 )], ['O', (-1.0 ,-1.0+.1,-1.0+.2)], ['O', (-1.0+.2,-1.0 ,-1.0+.1)], ['O', (-1.0+.1,-1.0+.2,-1.0 )]] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'T') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'D2') self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 4, 8, 12], [1, 5, 11, 15], [2, 6, 10, 13], [3, 7, 9, 14]])
def test_detect_symm_c2(self): atoms = [['H', (1., 0., 1.)], ['H', (1., 0., -1.)], ['He', (0., -3., 2.)], ['He', (0., 3., -2.)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'C2') self.assertTrue(geom.check_symm('C2', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0, 1], [2, 3]])
def test_detect_symm_d2h_b(self): atoms = [['H', (1., 0., 2.)], ['He', (0., 1., 0.)], ['H', (-1., 0., -2.)], ['He', (0., -1., 0.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2h') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2h', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0, 2], [1, 3]])
def test_Dooh(self): atoms = [['H', (0, 0, 0)], ['H', (0, 0, -1)], ['H1', (0, 0, 1)]] basis = {'H': 'sto3g'} gpname, orig, axes = geom.detect_symm(atoms, basis) self.assertEqual(gpname, 'Dooh') self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 2]]) gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Dooh') self.assertTrue(geom.check_symm('Dooh', atoms, basis)) self.assertTrue(geom.check_symm('D2h', atoms, basis)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 2]]) atoms = [['H', (0, 0, 0)], ['H', (1, 0, 0)]] self.assertFalse(geom.check_symm('Dooh', atoms))
def test_detect_symm_c1(self): atoms = [['H', (1., 0., 0.)], ['He', (0., 1., 0.)], ['Li', (0., 0., 1.)], ['Be', (.5, .5, .5)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'C1') self.assertTrue(geom.check_given_symm('C1', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0], [1], [2], [3]])
def test_detect_symm_d2_a(self): atoms = [['H', (1., 0., 1.)], ['H', (1., 0., -1.)], ['He', (0., 0., 2.)], ['He', (2., 0., 2.)], ['He', (1., 1., -2.)], ['He', (1., -1., -2.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2d') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms('D2', atoms), [[0, 1], [2, 3, 4, 5]])
def test_d6h(self): atoms = ringhat(6, u) atoms = atoms[6:] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D6h') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0,3],[1,2,4,5],[6,7]]) self.assertTrue(geom.check_given_symm('D2h', atoms))
def test_d6h(self): atoms = ringhat(6, u) atoms = atoms[6:] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D6h') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3], [1, 2, 4, 5], [6, 7]]) self.assertTrue(geom.check_given_symm('D2h', atoms))
def test_detect_symm_d2h_b(self): atoms = [['H' , (1., 0., 2.)], ['He', (0., 1., 0.)], ['H' , (-1.,0.,-2.)], ['He', (0.,-1., 0.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2h') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2h', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0,2],[1,3]])
def test_td1(self): coords1 = numpy.dot(make4(1.5), u) atoms = [['C', c] for c in coords1] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Td') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'D2') self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 1, 2, 3]])
def test_detect_symm_ci(self): atoms = [['H', (1., 0., 0.)], ['He', (0., 1., 0.)], ['Li', (0., 0., 1.)], ['Be', (.5, .5, .5)], ['H', (-1., 0., 0.)], ['He', (0., -1., 0.)], ['Li', (0., 0., -1.)], ['Be', (-.5, -.5, -.5)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'Ci') self.assertTrue(geom.check_given_symm('Ci', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0, 4], [1, 5], [2, 6], [3, 7]])
def test_c5v(self): atoms = ringhat(5, u)[5:-1] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C5v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 1], [2, 4], [3], [5]])
def test_c5h(self): atoms = ringhat(5, u) gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C5h') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10,11]])
def test_detect_symm_d2_b(self): s2 = numpy.sqrt(.5) atoms = [['C', (0., 0., 1.)], ['C', (0., 0., -1.)], ['H', (1, 0., 2.)], ['H', (-1, 0., 2.)], ['H', (s2, s2, -2.)], ['H', (-s2, -s2, -2.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0, 1], [2, 3, 4, 5]])
def test_c5v(self): atoms = ringhat(5, u)[5:-1] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C5v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 4], [1, 3], [2], [5]])
def test_detect_symm_c1(self): atoms = [['H' , ( 1., 0., 0.)], ['He', ( 0., 1., 0.)], ['Li', ( 0., 0., 1.)], ['Be', ( .5, .5, .5)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'C1') self.assertTrue(geom.check_given_symm('C1', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0], [1], [2], [3]])
def test_detect_symm_cs3(self): atoms = [['H', (2., 1., 0.)], ['He', (0., 1., 0.)], ['Li', (-1., 2., 0.)], ['Be', (1., 0., 0.)], ['S', (.5, 1., -3)], ['S', (.5, 1., 3)]] coord = numpy.dot([a[1] for a in atoms], u) atoms = [[atoms[i][0], c] for i, c in enumerate(coord)] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(l, atoms), [[0], [1], [2], [3], [4, 5]])
def test_s4(self): atoms = [['C', (0.5, 0, 1)], ['O', (0.4, 0.2, 1)], ['C', (-0.5, 0, 1)], ['O', (-0.4, -0.2, 1)], ['C', (0, 0.5, -1)], ['O', (-0.2, 0.4, -1)], ['C', (0, -0.5, -1)], ['O', (0.2, -0.4, -1)]] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'S4') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 2], [1, 3], [4, 6], [5, 7]]) self.assertTrue(geom.check_given_symm('C2', atoms))
def test_td2(self): coords1 = make4(1.5) coords2 = make4(1.9) atoms = [['C', c] for c in coords1] + [['C', c] for c in coords2] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Td') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2v') self.assertTrue(geom.check_given_symm('C2v', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 1], [2, 3], [4, 5], [6, 7]])
def test_c2v(self): atoms = ringhat(6, u) atoms = atoms[6:] atoms[1][0] = 'C1' atoms[2][0] = 'C1' basis = {'C': 'sto3g', 'N':'sto3g', 'C1':'ccpvdz'} gpname, orig, axes = geom.detect_symm(atoms, basis) self.assertEqual(gpname, 'C2v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3], [1, 2], [4, 5], [6, 7]]) self.assertTrue(geom.check_given_symm('C2', atoms, basis))
def test_detect_symm_d2_a(self): atoms = [['H' , (1., 0., 1.)], ['H' , (1., 0.,-1.)], ['He', (0., 0., 2.)], ['He', (2., 0., 2.)], ['He', (1., 1.,-2.)], ['He', (1.,-1.,-2.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0, 1], [2, 3, 4, 5]])
def test_td2(self): coords1 = make4(1.5) coords2 = make4(1.9) atoms = [['C', c] for c in coords1] + [['C', c] for c in coords2] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Td') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'D2') self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 1, 2, 3], [4, 5, 6, 7]])
def test_c2v(self): atoms = ringhat(6, u) atoms = atoms[6:] atoms[1][0] = 'C1' atoms[2][0] = 'C1' basis = {'C': 'sto3g', 'N': 'sto3g', 'C1': 'ccpvdz'} gpname, orig, axes = geom.detect_symm(atoms, basis) self.assertEqual(gpname, 'C2v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3], [1, 2], [4, 5], [6, 7]]) self.assertTrue(geom.check_given_symm('C2', atoms, basis))
def test_detect_symm_d2_b(self): s2 = numpy.sqrt(.5) atoms = [['C', (0., 0., 1.)], ['C', (0., 0.,-1.)], ['H', ( 1, 0., 2.)], ['H', (-1, 0., 2.)], ['H', ( s2, s2,-2.)], ['H', (-s2,-s2,-2.)]] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'D2') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0, 1], [2, 3, 4, 5]])
def test_td3(self): coords1 = make4(1.5) coords2 = make4(1.9) atoms = [['C', c] for c in coords1] + [['C', c] for c in coords2] atoms[2][0] = 'C1' gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C3v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 3], [2], [4], [5, 7], [6]])
def test_c3v(self): coords1 = numpy.dot(make4(1.5), u) coords2 = numpy.dot(make4(1.9), u) atoms = [['C', c] for c in coords1] + [['C', c] for c in coords2] atoms[2][0] = 'C1' gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C3v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3], [1], [2], [4, 7], [5], [6]])
def test_c3v(self): coords1 = numpy.dot(make4(1.5), u) coords2 = numpy.dot(make4(1.9), u) atoms = [['C', c] for c in coords1] + [['C', c] for c in coords2] atoms[2][0] = 'C1' gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'C3v') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 1], [2], [3], [4, 5], [6], [7]])
def test_detect_symm_s4(self): atoms = [['H', (-1,-1.,-2.)], ['H', ( 1, 1.,-2.)], ['C', (-.9,-1.,-2.)], ['C', (.9, 1.,-2.)], ['H', ( 1,-1., 2.)], ['H', (-1, 1., 2.)], ['C', ( 1,-.9, 2.)], ['C', (-1, .9, 2.)],] l, orig, axes = geom.detect_symm(atoms) self.assertEqual(l, 'S4') atoms = geom.shift_atom(atoms, orig, axes) self.assertTrue(geom.check_given_symm('C2', atoms)) self.assertEqual(geom.symm_identical_atoms('C2',atoms), [[0, 1], [2, 3], [4, 5], [6, 7]])
def test_d5d(self): coord1 = ring(5) coord2 = ring(5, numpy.pi/5) coord1[:,2] = 1 coord2[:,2] =-1 atoms = [['H', c] for c in numpy.vstack((coord1,coord2))] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D5d') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2h') self.assertTrue(geom.check_given_symm('C2h', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3, 5, 7], [1, 2, 8, 9], [4, 6]])
def test_detect_symm_ci(self): atoms = [['H' , ( 1., 0., 0.)], ['He', ( 0., 1., 0.)], ['Li', ( 0., 0., 1.)], ['Be', ( .5, .5, .5)], ['H' , (-1., 0., 0.)], ['He', ( 0.,-1., 0.)], ['Li', ( 0., 0.,-1.)], ['Be', (-.5,-.5,-.5)]] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'Ci') self.assertTrue(geom.check_given_symm('Ci', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0, 4], [1, 5], [2, 6], [3, 7]])
def test_detect_symm_cs3(self): atoms = [['H' , ( 2.,1., 0.)], ['He', ( 0.,1., 0.)], ['Li', (-1.,2., 0.)], ['Be', ( 1.,0., 0.)], ['S' , ( .5,1., -3)], ['S' , ( .5,1., 3)]] coord = numpy.dot([a[1] for a in atoms], u) atoms = [[atoms[i][0], c] for i,c in enumerate(coord)] l, orig, axes = geom.detect_symm(atoms) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(l, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(l,atoms), [[0], [1], [2], [3], [4, 5]])
def test_d5d(self): coord1 = ring(5) coord2 = ring(5, numpy.pi / 5) coord1[:, 2] = 1 coord2[:, 2] = -1 atoms = [['H', c] for c in numpy.vstack((coord1, coord2))] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'D5d') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'C2h') self.assertTrue(geom.check_given_symm('C2h', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 3, 5, 7], [1, 2, 8, 9], [4, 6]])
def test_s4(self): atoms = [['C', ( 0.5, 0 , 1)], ['O', ( 0.4, 0.2 , 1)], ['C', ( -0.5, 0 , 1)], ['O', ( -0.4, -0.2 , 1)], ['C', ( 0 , 0.5 , -1)], ['O', ( -0.2, 0.4 , -1)], ['C', ( 0 , -0.5 , -1)], ['O', ( 0.2, -0.4 , -1)]] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'S4') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 2], [1, 3], [4, 6], [5, 7]]) self.assertTrue(geom.check_given_symm('C2', atoms))
def test_ih1(self): coords = numpy.dot(make60(1.5, 1), u) atoms = [['C', c] for c in coords] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Ih') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Ci') self.assertTrue(geom.check_given_symm('Ci', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 55], [1, 56], [2, 57], [3, 58], [4, 59], [5, 30], [6, 31], [7, 32], [8, 33], [9, 34], [10, 35], [11, 36], [12, 37], [13, 38], [14, 39], [15, 40], [16, 41], [17, 42], [18, 43], [19, 44], [20, 45], [21, 46], [22, 47], [23, 48], [24, 49], [25, 50], [26, 51], [27, 52], [28, 53], [29, 54]])
def test_ih1(self): coords = make60(1.5, 1) atoms = [['C', c] for c in coords] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Ih') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Cs') self.assertTrue(geom.check_given_symm('Cs', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0], [1, 4], [2, 3], [5], [6, 9], [7, 8], [10, 25], [11, 29], [12, 28], [13, 27], [14, 26], [15, 20], [16, 24], [17, 23], [18, 22], [19, 21], [30], [31, 34], [32, 33], [35, 50], [36, 54], [37, 53], [38, 52], [39, 51], [40, 45], [41, 49], [42, 48], [43, 47], [44, 46], [55], [56, 59], [57, 58]])
def test_ih1(self): coords = numpy.dot(make60(1.5, 1), u) atoms = [['C', c] for c in coords] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Ih') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'Ci') self.assertTrue(geom.check_given_symm('Ci', atoms)) self.assertEqual( geom.symm_identical_atoms(gpname, atoms), [[0, 55], [1, 56], [2, 57], [3, 58], [4, 59], [5, 30], [6, 31], [7, 32], [8, 33], [9, 34], [10, 35], [11, 36], [12, 37], [13, 38], [14, 39], [15, 40], [16, 41], [17, 42], [18, 43], [19, 44], [20, 45], [21, 46], [22, 47], [23, 48], [24, 49], [25, 50], [26, 51], [27, 52], [28, 53], [29, 54]])
def test_th(self): atoms = [['C', ( 1.0 ,-1.0 , 1.0 )], ['O', ( 1.0-.1,-1.0+.2, 1.0 )], ['O', ( 1.0 ,-1.0+.1, 1.0-.2)], ['O', ( 1.0-.2,-1.0 , 1.0-.1)], ['C', ( 1.0 , 1.0 , 1.0 )], ['O', ( 1.0-.1, 1.0-.2, 1.0 )], ['O', ( 1.0 , 1.0-.1, 1.0-.2)], ['O', ( 1.0-.2, 1.0 , 1.0-.1)], ['C', (-1.0 , 1.0 , 1.0 )], ['O', (-1.0+.1, 1.0-.2, 1.0 )], ['O', (-1.0 , 1.0-.1, 1.0-.2)], ['O', (-1.0+.2, 1.0 , 1.0-.1)], ['C', (-1.0 ,-1.0 , 1.0 )], ['O', (-1.0+.1,-1.0+.2, 1.0 )], ['O', (-1.0 ,-1.0+.1, 1.0-.2)], ['O', (-1.0+.2,-1.0 , 1.0-.1)], ['C', ( 1.0 ,-1.0 ,-1.0 )], ['O', ( 1.0-.2,-1.0 ,-1.0+.1)], ['O', ( 1.0 ,-1.0+.1,-1.0+.2)], ['O', ( 1.0-.1,-1.0+.2,-1.0 )], ['C', ( 1.0 , 1.0 ,-1.0 )], ['O', ( 1.0-.2, 1.0 ,-1.0+.1)], ['O', ( 1.0 , 1.0-.1,-1.0+.2)], ['O', ( 1.0-.1, 1.0-.2,-1.0 )], ['C', (-1.0 , 1.0 ,-1.0 )], ['O', (-1.0+.2, 1.0 ,-1.0+.1)], ['O', (-1.0 , 1.0-.1,-1.0+.2)], ['O', (-1.0+.1, 1.0-.2,-1.0 )], ['C', (-1.0 ,-1.0 ,-1.0 )], ['O', (-1.0 ,-1.0+.1,-1.0+.2)], ['O', (-1.0+.2,-1.0 ,-1.0+.1)], ['O', (-1.0+.1,-1.0+.2,-1.0 )]] gpname, orig, axes = geom.detect_symm(atoms) self.assertEqual(gpname, 'Th') gpname, axes = geom.subgroup(gpname, axes) atoms = geom.shift_atom(atoms, orig, axes) self.assertEqual(gpname, 'D2') self.assertTrue(geom.check_given_symm('D2', atoms)) self.assertEqual(geom.symm_identical_atoms(gpname, atoms), [[0, 8, 20, 28], [1, 9, 23, 31], [2, 10, 22, 29], [3, 11, 21, 30], [4, 12, 16, 24], [5, 13, 19, 27], [6, 14, 18, 26], [7, 15, 17, 25]])
def linearmole_symm_adapted_basis(mol, gpname, eql_atom_ids=None): assert(gpname in ('Dooh', 'Coov')) assert(not mol.cart) if eql_atom_ids is None: eql_atom_ids = geom.symm_identical_atoms(gpname, mol._atom) aoslice = mol.aoslice_by_atom() basoff = aoslice[:,2] nao = mol.nao_nr() sodic = {} shalf = numpy.sqrt(.5) def plus(i0, i1): c = numpy.zeros(nao) c[i0] = c[i1] = shalf return c def minus(i0, i1): c = numpy.zeros(nao) c[i0] = shalf c[i1] =-shalf return c def identity(i0): c = numpy.zeros(nao) c[i0] = 1 return c def add_so(irrep_name, c): if irrep_name in sodic: sodic[irrep_name].append(c) else: sodic[irrep_name] = [c] if gpname == 'Dooh': for atom_ids in eql_atom_ids: if len(atom_ids) == 2: at0 = atom_ids[0] at1 = atom_ids[1] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i*degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 idx1 = basoff[at1] + aoff + 1 add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus (idx0, idx1)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff - 1 idy1 = basoff[at1] + aoff add_so('E1ux', plus (idx0, idx1)) add_so('E1uy', plus (idy0, idy1)) add_so('E1gx', minus(idx0, idx1)) add_so('E1gy', minus(idy0, idy1)) else: for i in range(nc): aoff = ip + i*degen + angl # m = 0 idx0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff if angl % 2: # p-sigma, f-sigma add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus (idx0, idx1)) else: # s-sigma, d-sigma add_so('A1g', plus (idx0, idx1)) add_so('A1u', minus(idx0, idx1)) # +/-m for m in range(1,angl+1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m idx1 = basoff[at1] + aoff + m idy1 = basoff[at1] + aoff - m if angl % 2: # odd parity add_so('E%dux'%m, plus (idx0, idx1)) add_so('E%duy'%m, plus (idy0, idy1)) add_so('E%dgx'%m, minus(idx0, idx1)) add_so('E%dgy'%m, minus(idy0, idy1)) else: add_so('E%dgy'%m, plus (idy0, idy1)) add_so('E%dgx'%m, plus (idx0, idx1)) add_so('E%duy'%m, minus(idy0, idy1)) add_so('E%dux'%m, minus(idx0, idx1)) ip += nc * degen elif len(atom_ids) == 1: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i*degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1u', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1uy', identity(idy0)) add_so('E1ux', identity(idx0)) else: for i in range(nc): aoff = ip + i*degen + angl idx0 = basoff[at0] + aoff # m = 0 if angl % 2: add_so('A1u', identity(idx0)) else: add_so('A1g', identity(idx0)) # +/-m for m in range(1,angl+1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m if angl % 2: # p, f functions add_so('E%dux'%m, identity(idx0)) add_so('E%duy'%m, identity(idy0)) else: # d, g functions add_so('E%dgy'%m, identity(idy0)) add_so('E%dgx'%m, identity(idx0)) ip += nc * degen elif gpname == 'Coov': for atom_ids in eql_atom_ids: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i*degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1x', identity(idx0)) add_so('E1y', identity(idy0)) else: for i in range(nc): aoff = ip + i*degen + angl idx0 = basoff[at0] + aoff # m = 0 add_so('A1', identity(idx0)) # +/-m for m in range(1,angl+1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m add_so('E%dx'%m, identity(idx0)) add_so('E%dy'%m, identity(idy0)) ip += nc * degen so = [] irrep_ids = [] irrep_names = list(sodic.keys()) for irname in irrep_names: irrep_ids.append(linearmole_irrep_symb2id(gpname, irname)) idx = numpy.argsort(irrep_ids) for i in idx: so.append(numpy.vstack(sodic[irrep_names[i]]).T) irrep_ids = [irrep_ids[i] for i in idx] return so, irrep_ids
def linearmole_symm_adapted_basis(mol, gpname, eql_atom_ids=None): assert (gpname in ('Dooh', 'Coov')) assert (not mol.cart) if eql_atom_ids is None: eql_atom_ids = geom.symm_identical_atoms(gpname, mol._atom) aoslice = mol.aoslice_by_atom() basoff = aoslice[:, 2] nao = mol.nao_nr() sodic = {} shalf = numpy.sqrt(.5) def plus(i0, i1): c = numpy.zeros(nao) c[i0] = c[i1] = shalf return c def minus(i0, i1): c = numpy.zeros(nao) c[i0] = shalf c[i1] = -shalf return c def identity(i0): c = numpy.zeros(nao) c[i0] = 1 return c def add_so(irrep_name, c): if irrep_name in sodic: sodic[irrep_name].append(c) else: sodic[irrep_name] = [c] if gpname == 'Dooh': for atom_ids in eql_atom_ids: if len(atom_ids) == 2: at0 = atom_ids[0] at1 = atom_ids[1] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 idx1 = basoff[at1] + aoff + 1 add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus(idx0, idx1)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff - 1 idy1 = basoff[at1] + aoff add_so('E1ux', plus(idx0, idx1)) add_so('E1uy', plus(idy0, idy1)) add_so('E1gx', minus(idx0, idx1)) add_so('E1gy', minus(idy0, idy1)) else: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff if angl % 2: # p-sigma, f-sigma add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus(idx0, idx1)) else: # s-sigma, d-sigma add_so('A1g', plus(idx0, idx1)) add_so('A1u', minus(idx0, idx1)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m idx1 = basoff[at1] + aoff + m idy1 = basoff[at1] + aoff - m if angl % 2: # odd parity add_so('E%dux' % m, plus(idx0, idx1)) add_so('E%duy' % m, plus(idy0, idy1)) add_so('E%dgx' % m, minus(idx0, idx1)) add_so('E%dgy' % m, minus(idy0, idy1)) else: add_so('E%dgy' % m, plus(idy0, idy1)) add_so('E%dgx' % m, plus(idx0, idx1)) add_so('E%duy' % m, minus(idy0, idy1)) add_so('E%dux' % m, minus(idx0, idx1)) ip += nc * degen elif len(atom_ids) == 1: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1u', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1uy', identity(idy0)) add_so('E1ux', identity(idx0)) else: for i in range(nc): aoff = ip + i * degen + angl idx0 = basoff[at0] + aoff # m = 0 if angl % 2: add_so('A1u', identity(idx0)) else: add_so('A1g', identity(idx0)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m if angl % 2: # p, f functions add_so('E%dux' % m, identity(idx0)) add_so('E%duy' % m, identity(idy0)) else: # d, g functions add_so('E%dgy' % m, identity(idy0)) add_so('E%dgx' % m, identity(idx0)) ip += nc * degen elif gpname == 'Coov': for atom_ids in eql_atom_ids: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1x', identity(idx0)) add_so('E1y', identity(idy0)) else: for i in range(nc): aoff = ip + i * degen + angl idx0 = basoff[at0] + aoff # m = 0 add_so('A1', identity(idx0)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m add_so('E%dx' % m, identity(idx0)) add_so('E%dy' % m, identity(idy0)) ip += nc * degen so = [] irrep_ids = [] irrep_names = list(sodic.keys()) for irname in irrep_names: irrep_ids.append(linearmole_irrep_symb2id(gpname, irname)) idx = numpy.argsort(irrep_ids) for i in idx: so.append(numpy.vstack(sodic[irrep_names[i]]).T) irrep_ids = [irrep_ids[i] for i in idx] return so, irrep_ids
def symm_adapted_basis(mol, gpname, eql_atom_ids=None): if eql_atom_ids is None: eql_atom_ids = geom.symm_identical_atoms(gpname, mol._atom) if gpname in ('Dooh', 'Coov'): return linearmole_symm_adapted_basis(mol, gpname, eql_atom_ids) ops = numpy.asarray( [param.D2H_OPS[op] for op in param.OPERATOR_TABLE[gpname]]) chartab = numpy.array([x[1:] for x in param.CHARACTER_TABLE[gpname]]) nirrep = chartab.__len__() aoslice = mol.aoslice_by_atom() nao = mol.nao_nr() atom_coords = mol.atom_coords() sodic = [[] for i in range(8)] for atom_ids in eql_atom_ids: r0 = mol.atom_coord(atom_ids[0]) op_coords = numpy.einsum('x,nxy->ny', r0, ops) # Using ops to generate other atoms from atom_ids[0] coords0 = atom_coords[atom_ids] natm = len(atom_ids) dc = abs(op_coords.reshape(-1, 1, 3) - coords0).sum(axis=2) op_relate_idx = numpy.argwhere(dc < geom.TOLERANCE)[:, 1] ao_loc = numpy.array([aoslice[atom_ids[i], 2] for i in op_relate_idx]) b0, b1 = aoslice[atom_ids[0], :2] ip = 0 for ib in range(b0, b1): l = mol.bas_angular(ib) if mol.cart: degen = (l + 1) * (l + 2) // 2 cbase = numpy.zeros((degen, nirrep, nao)) for op_id, op in enumerate(ops): n = 0 for x in range(l, -1, -1): for y in range(l - x, -1, -1): z = l - x - y idx = ao_loc[op_id] + n sign = op[0, 0]**x * op[1, 1]**y * op[2, 2]**z cbase[n, :, idx] += sign * chartab[:, op_id] n += 1 else: degen = l * 2 + 1 cbase = numpy.zeros((degen, nirrep, nao)) for op_id, op in enumerate(param.OPERATOR_TABLE[gpname]): for n, m in enumerate(range(-l, l + 1)): idx = ao_loc[op_id] + n if tot_parity_odd(op, l, m): cbase[n, :, idx] -= chartab[:, op_id] else: cbase[n, :, idx] += chartab[:, op_id] norms = numpy.sqrt(numpy.einsum('mij,mij->mi', cbase, cbase)) for i in range(mol.bas_nctr(ib)): for n, ir in numpy.argwhere(norms > 1e-12): c = numpy.zeros(nao) c[ip:] = cbase[n, ir, :nao - ip] / norms[n, ir] sodic[ir].append(c) ip += degen so = [] irrep_ids = [] for ir, c in enumerate(sodic): if len(c) > 0: irrep_ids.append(ir) so.append(numpy.vstack(c).T) return so, irrep_ids
if __name__ == "__main__": h2o = pyscf.gto.Mole() h2o.verbose = 0 h2o.output = None h2o.atom = [['O' , (1. , 0. , 0. ,)], [1 , (0. , -.757 , 0.587,)], [1 , (0. , 0.757 , 0.587,)] ] h2o.basis = {'H': 'cc-pvdz', 'O': 'cc-pvdz',} h2o.build() gpname, origin, axes = geom.detect_symm(h2o.atom) atoms = pyscf.gto.mole.format_atom(h2o.atom, origin, axes) print(gpname) eql_atoms = geom.symm_identical_atoms(gpname, atoms) print(symm_adapted_basis(gpname, eql_atoms, atoms, h2o._basis)) mol = pyscf.gto.M( atom = [['H', (0,0,0)], ['H', (0,0,-1)], ['H', (0,0,1)]], basis = 'ccpvtz') gpname, orig, axes = geom.detect_symm(mol.atom) atoms = pyscf.gto.mole.format_atom(mol.atom, orig, axes) print(gpname) eql_atoms = geom.symm_identical_atoms(gpname, atoms) print(symm_adapted_basis(gpname, eql_atoms, atoms, mol._basis)[1]) mol = pyscf.gto.M( atom = [['H', (0,0,0)], ['H', (0,0,-1)], ['He', (0,0,1)]], basis = 'ccpvtz') gpname, orig, axes = geom.detect_symm(mol.atom)
def symm_adapted_basis(mol, gpname, eql_atom_ids=None): if eql_atom_ids is None: eql_atom_ids = geom.symm_identical_atoms(gpname, mol._atom) if gpname in ('Dooh', 'Coov'): return linearmole_symm_adapted_basis(mol, gpname, eql_atom_ids) ops = numpy.asarray([param.D2H_OPS[op] for op in param.OPERATOR_TABLE[gpname]]) chartab = numpy.array([x[1:] for x in param.CHARACTER_TABLE[gpname]]) nirrep = chartab.__len__() aoslice = mol.aoslice_by_atom() nao = mol.nao_nr() atom_coords = mol.atom_coords() sodic = [[] for i in range(8)] for atom_ids in eql_atom_ids: r0 = mol.atom_coord(atom_ids[0]) op_coords = numpy.einsum('x,nxy->ny', r0, ops) # Using ops to generate other atoms from atom_ids[0] coords0 = atom_coords[atom_ids] natm = len(atom_ids) dc = abs(op_coords.reshape(-1,1,3) - coords0).sum(axis=2) op_relate_idx = numpy.argwhere(dc < geom.TOLERANCE)[:,1] ao_loc = numpy.array([aoslice[atom_ids[i],2] for i in op_relate_idx]) b0, b1 = aoslice[atom_ids[0],:2] ip = 0 for ib in range(b0, b1): l = mol.bas_angular(ib) if mol.cart: degen = (l + 1) * (l + 2) // 2 cbase = numpy.zeros((degen,nirrep,nao)) for op_id, op in enumerate(ops): n = 0 for x in range(l, -1, -1): for y in range(l-x, -1, -1): z = l-x-y idx = ao_loc[op_id] + n sign = op[0,0]**x * op[1,1]**y * op[2,2]**z cbase[n,:,idx] += sign * chartab[:,op_id] n += 1 else: degen = l * 2 + 1 cbase = numpy.zeros((degen,nirrep,nao)) for op_id, op in enumerate(param.OPERATOR_TABLE[gpname]): for n, m in enumerate(range(-l, l+1)): idx = ao_loc[op_id] + n if tot_parity_odd(op, l, m): cbase[n,:,idx] -= chartab[:,op_id] else: cbase[n,:,idx] += chartab[:,op_id] norms = numpy.sqrt(numpy.einsum('mij,mij->mi', cbase, cbase)) for i in range(mol.bas_nctr(ib)): for n, ir in numpy.argwhere(norms > 1e-12): c = numpy.zeros(nao) c[ip:] = cbase[n,ir,:nao-ip] / norms[n,ir] sodic[ir].append(c) ip += degen so = [] irrep_ids = [] for ir, c in enumerate(sodic): if len(c) > 0: irrep_ids.append(ir) so.append(numpy.vstack(c).T) return so, irrep_ids
0.587, )], [1, ( 0., 0.757, 0.587, )]] h2o.basis = { 'H': 'cc-pvdz', 'O': 'cc-pvdz', } h2o.build() gpname, origin, axes = geom.detect_symm(h2o._atom) atoms = gto.format_atom(h2o._atom, origin, axes) h2o.build(False, False, atom=atoms) print(gpname) eql_atoms = geom.symm_identical_atoms(gpname, atoms) print(symm_adapted_basis(h2o, gpname, eql_atoms)[1]) mol = gto.M(atom=[['H', (0, 0, 0)], ['H', (0, 0, -1)], ['H', (0, 0, 1)]], basis='ccpvtz', charge=1) gpname, orig, axes = geom.detect_symm(mol._atom) atoms = gto.format_atom(mol._atom, orig, axes) mol.build(False, False, atom=atoms) print(gpname) eql_atoms = geom.symm_identical_atoms(gpname, atoms) print(symm_adapted_basis(mol, gpname, eql_atoms)[1]) mol = gto.M(atom=[['H', (0, 0, 0)], ['H', (0, 0, -1)], ['He', (0, 0, 1)]], basis='ccpvtz') gpname, orig, axes = geom.detect_symm(mol._atom)
def linearmole_symm_adapted_basis(mol, gpname, orig=0, coordinates=None): assert (gpname in ('Dooh', 'Coov')) assert (not mol.cart) if coordinates is None: coordinates = numpy.eye(3) prop_atoms = mol.format_atom(mol._atom, orig, coordinates, 'Bohr') eql_atom_ids = geom.symm_identical_atoms(gpname, prop_atoms) aoslice = mol.aoslice_by_atom() basoff = aoslice[:, 2] nao = mol.nao_nr() sodic = {} shalf = numpy.sqrt(.5) def plus(i0, i1): c = numpy.zeros(nao) c[i0] = c[i1] = shalf return c def minus(i0, i1): c = numpy.zeros(nao) c[i0] = shalf c[i1] = -shalf return c def identity(i0): c = numpy.zeros(nao) c[i0] = 1 return c def add_so(irrep_name, c): if irrep_name in sodic: sodic[irrep_name].append(c) else: sodic[irrep_name] = [c] if gpname == 'Dooh': for atom_ids in eql_atom_ids: if len(atom_ids) == 2: at0 = atom_ids[0] at1 = atom_ids[1] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 idx1 = basoff[at1] + aoff + 1 add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus(idx0, idx1)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff - 1 idy1 = basoff[at1] + aoff add_so('E1ux', plus(idx0, idx1)) add_so('E1uy', plus(idy0, idy1)) add_so('E1gx', minus(idx0, idx1)) add_so('E1gy', minus(idy0, idy1)) else: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff idx1 = basoff[at1] + aoff if angl % 2: # p-sigma, f-sigma add_so('A1g', minus(idx0, idx1)) add_so('A1u', plus(idx0, idx1)) else: # s-sigma, d-sigma add_so('A1g', plus(idx0, idx1)) add_so('A1u', minus(idx0, idx1)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m idx1 = basoff[at1] + aoff + m idy1 = basoff[at1] + aoff - m if angl % 2: # odd parity add_so('E%dux' % m, plus(idx0, idx1)) add_so('E%duy' % m, plus(idy0, idy1)) add_so('E%dgx' % m, minus(idx0, idx1)) add_so('E%dgy' % m, minus(idy0, idy1)) else: add_so('E%dgy' % m, plus(idy0, idy1)) add_so('E%dgx' % m, plus(idx0, idx1)) add_so('E%duy' % m, minus(idy0, idy1)) add_so('E%dux' % m, minus(idx0, idx1)) ip += nc * degen elif len(atom_ids) == 1: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1u', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1uy', identity(idy0)) add_so('E1ux', identity(idx0)) else: for i in range(nc): aoff = ip + i * degen + angl idx0 = basoff[at0] + aoff # m = 0 if angl % 2: add_so('A1u', identity(idx0)) else: add_so('A1g', identity(idx0)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m if angl % 2: # p, f functions add_so('E%dux' % m, identity(idx0)) add_so('E%duy' % m, identity(idy0)) else: # d, g functions add_so('E%dgy' % m, identity(idy0)) add_so('E%dgx' % m, identity(idx0)) ip += nc * degen elif gpname == 'Coov': for atom_ids in eql_atom_ids: at0 = atom_ids[0] ip = 0 b0, b1, p0, p1 = aoslice[at0] for ib in range(b0, b1): angl = mol.bas_angular(ib) nc = mol.bas_nctr(ib) degen = angl * 2 + 1 if angl == 1: for i in range(nc): aoff = ip + i * degen + angl # m = 0 idx0 = basoff[at0] + aoff + 1 add_so('A1', identity(idx0)) # m = +/- 1 idx0 = basoff[at0] + aoff - 1 idy0 = basoff[at0] + aoff add_so('E1x', identity(idx0)) add_so('E1y', identity(idy0)) else: for i in range(nc): aoff = ip + i * degen + angl idx0 = basoff[at0] + aoff # m = 0 add_so('A1', identity(idx0)) # +/-m for m in range(1, angl + 1): idx0 = basoff[at0] + aoff + m idy0 = basoff[at0] + aoff - m add_so('E%dx' % m, identity(idx0)) add_so('E%dy' % m, identity(idy0)) ip += nc * degen irrep_ids = [] irrep_names = list(sodic.keys()) for irname in irrep_names: irrep_ids.append(linearmole_irrep_symb2id(gpname, irname)) irrep_idx = numpy.argsort(irrep_ids) irrep_ids = [irrep_ids[i] for i in irrep_idx] ao_loc = mol.ao_loc_nr() l_idx = {} ANG_OF = 1 for l in range(mol._bas[:, ANG_OF].max() + 1): idx = [ numpy.arange(ao_loc[ib], ao_loc[ib + 1]) for ib in numpy.where(mol._bas[:, ANG_OF] == l)[0] ] if idx: l_idx[l] = numpy.hstack(idx) Ds = _ao_rotation_matrices(mol, coordinates) so = [] for i in irrep_idx: c_ir = numpy.vstack(sodic[irrep_names[i]]).T nso = c_ir.shape[1] for l, idx in l_idx.items(): c = c_ir[idx].reshape(-1, Ds[l].shape[1], nso) c_ir[idx] = numpy.einsum('nm,smp->snp', Ds[l], c).reshape(-1, nso) so.append(c_ir) return so, irrep_ids
def symm_adapted_basis(mol, gpname, orig=0, coordinates=None): if gpname == 'SO3': return so3_symm_adapted_basis(mol, gpname, orig, coordinates) elif gpname in ('Dooh', 'Coov'): return linearmole_symm_adapted_basis(mol, gpname, orig, coordinates) # prop_atoms are the atoms relocated wrt the charge center with proper # orientation if coordinates is None: coordinates = numpy.eye(3) prop_atoms = mol.format_atom(mol._atom, orig, coordinates, 'Bohr') eql_atom_ids = geom.symm_identical_atoms(gpname, prop_atoms) ops = numpy.asarray( [param.D2H_OPS[op] for op in param.OPERATOR_TABLE[gpname]]) chartab = numpy.array([x[1:] for x in param.CHARACTER_TABLE[gpname]]) nirrep = chartab.__len__() aoslice = mol.aoslice_by_atom() nao = mol.nao_nr() atom_coords = numpy.array([a[1] for a in prop_atoms]) sodic = [[] for i in range(8)] for atom_ids in eql_atom_ids: r0 = atom_coords[atom_ids[0]] op_coords = numpy.einsum('x,nxy->ny', r0, ops) # Using ops to generate other atoms from atom_ids[0] coords0 = atom_coords[atom_ids] dc = abs(op_coords.reshape(-1, 1, 3) - coords0).max(axis=2) op_relate_idx = numpy.argwhere(dc < geom.TOLERANCE)[:, 1] ao_loc = numpy.array([aoslice[atom_ids[i], 2] for i in op_relate_idx]) b0, b1 = aoslice[atom_ids[0], :2] ip = 0 for ib in range(b0, b1): l = mol.bas_angular(ib) if mol.cart: degen = (l + 1) * (l + 2) // 2 cbase = numpy.zeros((degen, nirrep, nao)) for op_id, op in enumerate(ops): n = 0 for x in range(l, -1, -1): for y in range(l - x, -1, -1): z = l - x - y idx = ao_loc[op_id] + n sign = op[0, 0]**x * op[1, 1]**y * op[2, 2]**z cbase[n, :, idx] += sign * chartab[:, op_id] n += 1 else: degen = l * 2 + 1 cbase = numpy.zeros((degen, nirrep, nao)) for op_id, op in enumerate(param.OPERATOR_TABLE[gpname]): for n, m in enumerate(range(-l, l + 1)): idx = ao_loc[op_id] + n if tot_parity_odd(op, l, m): cbase[n, :, idx] -= chartab[:, op_id] else: cbase[n, :, idx] += chartab[:, op_id] norms = numpy.sqrt(numpy.einsum('mij,mij->mi', cbase, cbase)) for i in range(mol.bas_nctr(ib)): for n, ir in numpy.argwhere(norms > 1e-12): c = numpy.zeros(nao) c[ip:] = cbase[n, ir, :nao - ip] / norms[n, ir] sodic[ir].append(c) ip += degen ao_loc = mol.ao_loc_nr() l_idx = {} ANG_OF = 1 for l in range(mol._bas[:, ANG_OF].max() + 1): idx = [ numpy.arange(ao_loc[ib], ao_loc[ib + 1]) for ib in numpy.where(mol._bas[:, ANG_OF] == l)[0] ] if idx: l_idx[l] = numpy.hstack(idx) Ds = _ao_rotation_matrices(mol, coordinates) so = [] irrep_ids = [] for ir, c in enumerate(sodic): if len(c) > 0: irrep_ids.append(ir) c_ir = numpy.vstack(c).T nso = c_ir.shape[1] for l, idx in l_idx.items(): c = c_ir[idx].reshape(-1, Ds[l].shape[1], nso) c_ir[idx] = numpy.einsum('nm,smp->snp', Ds[l], c).reshape(-1, nso) so.append(c_ir) return so, irrep_ids