Ejemplo n.º 1
0
    def test_0_constructor(self):
        # Test what the setup constructed
        self.assertEqual(len(self.empty.atom_numbers), 0)
        self.assertEqual(len(self.empty.coords), 0)
        self.assertEqual(self.empty.n_alpha, 0)
        self.assertEqual(self.empty.n_beta, 0)

        self.assertListEqual(self.water.atom_numbers.tolist(), [1, 8, 1])
        self.assertListEqual(self.water.coords[0].tolist(), [0, 0, 1])
        self.assertListEqual(self.water.coords[1].tolist(), [0, 0, 0])
        self.assertListEqual(self.water.coords[2].tolist(), [1, 0, 0])
        self.assertEqual(self.water.n_alpha, 5)
        self.assertEqual(self.water.n_beta, 5)

        self.assertListEqual(self.water_triplet.atom_numbers.tolist(),
                             [1, 8, 1])
        self.assertListEqual(self.water_triplet.coords[0].tolist(), [0, 0, 1])
        self.assertListEqual(self.water_triplet.coords[1].tolist(), [0, 0, 0])
        self.assertListEqual(self.water_triplet.coords[2].tolist(), [1, 0, 0])
        self.assertEqual(self.water_triplet.n_alpha, 6)
        self.assertEqual(self.water_triplet.n_beta, 4)

        self.assertListEqual(self.no.atom_numbers.tolist(), [7, 8])
        self.assertListEqual(self.no.coords[0].tolist(), [0, 0, 0])
        self.assertListEqual(self.no.coords[1].tolist(), [1, 0, 0])
        self.assertEqual(self.no.n_alpha, 8)
        self.assertEqual(self.no.n_beta, 7)

        self.assertListEqual(self.oxide.atom_numbers.tolist(), [8])
        self.assertListEqual(self.oxide.coords[0].tolist(), [0, 0, 0])
        self.assertEqual(self.oxide.n_alpha, 5)
        self.assertEqual(self.oxide.n_beta, 5)

        # Construction from atom names and atom numbers
        wat = molsturm.System(["hydrogen", "O", 1],
                              [[0, 0, 1], [0, 0, 0], [1, 0, 0]])
        self.assertListEqual(wat.atom_numbers.tolist(), [1, 8, 1])
        self.assertListEqual(wat.coords[0].tolist(), [0, 0, 1])
        self.assertListEqual(wat.coords[1].tolist(), [0, 0, 0])
        self.assertListEqual(wat.coords[2].tolist(), [1, 0, 0])
        self.assertEqual(wat.n_alpha, 5)
        self.assertEqual(wat.n_beta, 5)

        # Try to get a triplet oxygen wrongly
        with self.assertRaises(ValueError):
            molsturm.System(["O"], [0, 0, 0], (3, 5))

        # Missing the coord is ok if only a single atom
        ox = molsturm.System(["O"])
        self.assertListEqual(ox.coords[0].tolist(), [0, 0, 0])
        self.assertListEqual(self.oxide.atom_numbers.tolist(), [8])

        # But not if two or more
        with self.assertRaises(ValueError):
            molsturm.System(["O", "O"])

        # May miss the liss for one atom:
        ox = molsturm.System("O")
        self.assertListEqual(ox.coords[0].tolist(), [0, 0, 0])
        self.assertListEqual(self.oxide.atom_numbers.tolist(), [8])
Ejemplo n.º 2
0
    def setUpClass(cls):
        water_atoms = ["H", "O", "H"]
        water_coords = [[0, 0, 1], [0, 0, 0], [1, 0, 0]]
        no_atoms = ["N", "O"]
        no_coords = [[0, 0, 0], [1, 0, 0]]

        cls.empty = molsturm.System()
        cls.water = molsturm.System(water_atoms, water_coords)
        cls.water_triplet = molsturm.System(water_atoms, water_coords, (6, 4))
        cls.no = molsturm.System(no_atoms, no_coords)
        cls.oxide = molsturm.System(["O"], [[0, 0, 0]], (5, 5))
Ejemplo n.º 3
0
def run_hf(xyz,
           basis,
           charge=0,
           multiplicity=1,
           conv_tol=1e-12,
           conv_tol_grad=1e-8,
           max_iter=150):

    import molsturm

    # Quick-and-dirty xyz parser:
    geom = xyz.split()
    n_atom = len(geom) // 4
    assert n_atom * 4 == len(geom)
    atoms = [geom[i * 4] for i in range(n_atom)]
    coords = [[
        float(geom[i * 4 + 1]),
        float(geom[i * 4 + 2]),
        float(geom[i * 4 + 3])
    ] for i in range(n_atom)]

    mol = molsturm.System(atoms, coords)
    mol.charge = charge
    mol.multiplicity = multiplicity

    return molsturm.hartree_fock(mol,
                                 basis_type="gaussian",
                                 basis_set_name=basis_remap.get(basis, basis),
                                 conv_tol=conv_tol_grad,
                                 max_iter=max_iter)
def dump_integrals_gaussian(atoms,
                            coords,
                            electrons,
                            basis_set_name,
                            ifile=None):
    system = molsturm.System(atoms, coords, electrons)

    params = molsturm.ScfParameters()
    params.system = system
    params.basis = molsturm.construct_basis("gaussian",
                                            params.system,
                                            basis_set_name=basis_set_name)

    if ifile is None:
        latoms = [a.lower() for a in atoms]
        ifile = "integrals_{}_{}.hdf5".format("".join(latoms), basis_set_name)

    with h5py.File(ifile, "w") as h5f:
        write_integrals_to_hdf5(params, h5f)

        g_discr = h5f.create_group("discretisation")
        g_discr.create_dataset("basis_type",
                               data="gaussian",
                               dtype=h5py.special_dtype(vlen=str))
        g_discr.create_dataset("basis_set_name",
                               dtype=h5py.special_dtype(vlen=str),
                               data=basis_set_name)
        g_discr.create_dataset("has_real_harmonics", data=1, dtype=np.uint8)
Ejemplo n.º 5
0
    def test_2_n_electrons_setter(self):
        oxy = molsturm.System("O")
        self.assertEqual(oxy.charge, 0)
        self.assertEqual(oxy.multiplicity, 1)

        oxy.n_electrons += 2
        self.assertEqual(oxy.charge, -2)
        self.assertEqual(oxy.multiplicity, 1)

        oxy = molsturm.System("O", electrons=(5, 3))
        self.assertEqual(oxy.charge, 0)
        self.assertEqual(oxy.multiplicity, 3)

        oxy.n_electrons += 2
        self.assertEqual(oxy.charge, -2)
        self.assertEqual(oxy.multiplicity, 3)

        oxy.n_electrons = 9
        self.assertEqual(oxy.charge, -1)
        self.assertEqual(oxy.multiplicity, 2)
Ejemplo n.º 6
0
    def test_2_multiplicity_setter(self):
        oxy = molsturm.System("O")
        self.assertEqual(oxy.charge, 0)
        self.assertEqual(oxy.multiplicity, 1)

        oxy.multiplicity = 3
        self.assertEqual(oxy.charge, 0)
        self.assertEqual(oxy.multiplicity, 3)

        with self.assertRaises(ValueError):
            oxy.multiplicity = 2
Ejemplo n.º 7
0
def main():
    carbon = molsturm.System("c")
    carbon.multiplicity = 3

    params = molsturm.ScfParameters()
    params.system = carbon
    params.basis = molsturm.construct_basis("sturmian/atomic/cs_reference_pc",
                                            params.system, k_exp=3.3, n_max=4,
                                            l_max=3)
    params["scf/eigensolver/method"] = "lapack"
    params["scf/print_iterations"] = True
    params["guess/eigensolver/method"] = "lapack"

    res = molsturm.self_consistent_field(params)
    molsturm.print_convergence_summary(res)
    molsturm.print_energies(res)
    molsturm.print_mo_occupation(res)
    molsturm.print_quote(res)
    return res
def dump_integrals_sturmian(atoms,
                            coords,
                            electrons,
                            k_exp,
                            n_max,
                            l_max,
                            m_max,
                            ifile=None):
    system = molsturm.System(atoms, coords, electrons)

    params = molsturm.ScfParameters()
    params.system = system
    basis = molsturm.construct_basis("sturmian/atomic",
                                     params.system,
                                     k_exp=k_exp,
                                     n_max=n_max,
                                     l_max=l_max,
                                     m_max=m_max)
    basis.backend = "cs_reference"
    params.basis = basis

    if ifile is None:
        latoms = [a.lower() for a in atoms]
        ifile = ("integrals_{}_{:02d}{:02d}{:02d}_{:.4f}.hdf5"
                 "".format("".join(latoms), n_max, l_max, m_max, k_exp))

    with h5py.File(ifile, "w") as h5f:
        write_integrals_to_hdf5(params, h5f)

        g_discr = h5f.create_group("discretisation")
        g_discr.create_dataset("basis_type",
                               data="sturmian/atomic",
                               dtype=h5py.special_dtype(vlen=str))
        g_discr.create_dataset("nlm_basis", data=basis.functions)
        g_discr.create_dataset("k_exp", data=k_exp)
        g_discr.create_dataset("n_max", data=n_max)
        g_discr.create_dataset("l_max", data=l_max)
        g_discr.create_dataset("m_max", data=m_max)
        g_discr.create_dataset("has_real_harmonics",
                               data=basis.has_real_harmonics,
                               dtype=np.uint8)
Ejemplo n.º 9
0
##
## molsturm is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with molsturm. If not, see <http://www.gnu.org/licenses/>.
##
## ---------------------------------------------------------------------
## vi: tabstop=2 shiftwidth=2 softtabstop=2 expandtab

import molsturm
import molsturm.posthf

sys = molsturm.System(["beryllium"], [[0, 0, 0]])
bas = molsturm.construct_basis("sturmian/atomic",
                               sys,
                               k_exp=2.1,
                               n_max=11,
                               l_max=0,
                               backend="cs_reference_pc")
res = molsturm.hartree_fock(sys, bas, conv_tol=1e-10, print_iterations=True)

molsturm.print_convergence_summary(res)
molsturm.print_energies(res)
molsturm.print_mo_occupation(res)
print()

res_adc = molsturm.posthf.mp2(res)
print("MP2 energy", res_adc["energy_mp2"])
Ejemplo n.º 10
0
        residual = ccd_residual(t2, state.fock, eri_asym)
        residual_norm = np.max(np.max(residual))
        print(fmt.format(n_iter, corr, residual_norm))

        # Quasi-Newton update step
        n_iter += 1
        t2 -= residual / ccd_approx_jacobian(t2, state.fock, eri_asym)

        if n_iter > 100:
            raise RuntimeError("CCD not converged after 100 iterations.")
    return corr, t2


if __name__ == "__main__":
    sys = molsturm.System(
        atoms=["O", "O"],
        coords=[(0, 0, 0), (0, 0, 2.8535)],
    )
    sys.multiplicity = 3
    state = molsturm.hartree_fock(sys, basis_type="gaussian",
                                  basis_set_name="6-31g", conv_tol=5e-7)

    corr, t2 = ccd(state)
    maxamp = np.max(np.abs(t2))
    print("CCD correlation energy: ", corr)
    print("Largest t2 amplitude:   ", maxamp)
    print()

    hf = state.energy_ground_state
    print("HF energy:              ", hf)
    print("CCD total energy:       ", corr + hf)
Ejemplo n.º 11
0
#!/usr/bin/env python3
## vi: tabstop=4 shiftwidth=4 softtabstop=4 expandtab
import adcc

import molsturm

# Run SCF in molsturm
atoms = ["O", "H", "H"]
coords = [[0, 0, 0],
          [0, 0, 1.795239827225189],
          [1.693194615993441, 0, -0.599043184453037]]
system = molsturm.System(atoms, coords)

hfres = molsturm.hartree_fock(system, basis_type="gaussian",
                              basis_set_name="sto-3g",
                              conv_tol=1e-12, print_iterations=True)

# Run an adc2 calculation:
singlets = adcc.adc2(hfres, n_singlets=5, conv_tol=1e-9)
triplets = adcc.adc2(singlets.matrix, n_triplets=3, conv_tol=1e-9)

print(singlets.describe())
print(triplets.describe())
Ejemplo n.º 12
0
    def test_2_adjust_electrons(self):
        oxy = molsturm.System("O")
        self.assertEqual(oxy.n_alpha, 4)
        self.assertEqual(oxy.n_beta, 4)
        self.assertEqual(oxy.multiplicity, 1)
        self.assertEqual(oxy.charge, 0)

        # Adjust multiplicity to make triplet
        oxy.adjust_electrons(multiplicity=3)
        self.assertEqual(oxy.n_alpha, 5)
        self.assertEqual(oxy.n_beta, 3)
        self.assertEqual(oxy.multiplicity, 3)
        self.assertEqual(oxy.charge, 0)

        # Adjust electrons to make doublet O^-
        oxy.adjust_electrons(charge=-1)
        self.assertEqual(oxy.n_alpha, 5)
        self.assertEqual(oxy.n_beta, 4)
        self.assertEqual(oxy.multiplicity, 2)
        self.assertEqual(oxy.charge, -1)

        # Adjust electrons to make quartet O^-
        oxy.adjust_electrons(multiplicity=4)
        self.assertEqual(oxy.n_alpha, 6)
        self.assertEqual(oxy.n_beta, 3)
        self.assertEqual(oxy.multiplicity, 4)
        self.assertEqual(oxy.charge, -1)

        # And go back to triplet oxygen
        oxy.adjust_electrons(charge=0, multiplicity=3)
        self.assertEqual(oxy.n_alpha, 5)
        self.assertEqual(oxy.n_beta, 3)
        self.assertEqual(oxy.multiplicity, 3)
        self.assertEqual(oxy.charge, 0)

        # Strip off all electrons:
        oxy.adjust_electrons(charge=8)
        self.assertEqual(oxy.n_alpha, 0)
        self.assertEqual(oxy.n_beta, 0)

        # Too large charge
        with self.assertRaises(ValueError):
            oxy.adjust_electrons(charge=9)

        # Invalid multiplicity number
        with self.assertRaises(ValueError):
            oxy.adjust_electrons(charge=0, multiplicity=2)
        with self.assertRaises(ValueError):
            oxy.adjust_electrons(charge=1, multiplicity=3)

        # All electrons in alpha:
        oxy.adjust_electrons(charge=0, multiplicity=9)
        self.assertEqual(oxy.n_alpha, 8)
        self.assertEqual(oxy.n_beta, 0)

        # Request larger multiplicity
        with self.assertRaises(ValueError):
            oxy.adjust_electrons(charge=0, multiplicity=11)

        # Change from triplet oxygen to triplet O^{2+}
        oxy.adjust_electrons(charge=0, multiplicity=3)
        oxy.adjust_electrons(charge=2)
        self.assertEqual(oxy.n_alpha, 4)
        self.assertEqual(oxy.n_beta, 2)
        self.assertEqual(oxy.multiplicity, 3)
        self.assertEqual(oxy.charge, 2)
Ejemplo n.º 13
0
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## molsturm is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with molsturm. If not, see <http://www.gnu.org/licenses/>.
##
## ---------------------------------------------------------------------
## vi: tabstop=2 shiftwidth=2 softtabstop=2 expandtab

import molsturm
import molsturm.posthf

sys = molsturm.System([4], [[0, 0, 0]])
res = molsturm.hartree_fock(sys, basis_type="gaussian", basis_set_name="cc-pvdz",
                            print_iterations=True, conv_tol=1e-10)
molsturm.print_convergence_summary(res)
molsturm.print_energies(res)
molsturm.print_mo_occupation(res)

res_adc = molsturm.posthf.mp2(res)
print("MP2 energy", res_adc["energy_mp2"])
print("tot energy", res_adc["energy_ground_state"])

molsturm.print_quote(res)
Ejemplo n.º 14
0
import h5py
import sys
import numpy as np

if len(sys.argv) != 2:
    raise SystemExit("Need hdf5 integrals file as first arg.")
ifile = sys.argv[1]

with h5py.File(ifile, "r") as h5f:
    nelec = list(h5f["system/nelec"])
    atom_numbers = np.array(h5f["system/atom_numbers"])
    coords = np.array(h5f["system/coords"])

    system = molsturm.System(
        atoms=atom_numbers,
        coords=coords,
        electrons=nelec,
    )
    params = molsturm.ScfParameters()
    params.system = system

    basis_type = str(h5f["discretisation/basis_type"].value)
    if basis_type == "gaussian":
        bas = str(h5f["discretisation/basis_set_name"].value)
        params.basis = molsturm.construct_basis("gaussian",
                                                params.system,
                                                basis_set_name=bas)
    elif basis_type == "sturmian/atomic":
        k_exp = float(h5f["discretisation/k_exp"].value)
        n_max = int(h5f["discretisation/n_max"].value)
        l_max = int(h5f["discretisation/l_max"].value)
Ejemplo n.º 15
0
#!/usr/bin/env python3

import molsturm
from molsturm import integrals
from scipy import linalg
import numpy as np

params = molsturm.ScfParameters()

# Supply molecular structure
atoms = ["Be"]  # as a list of names, symbols, atom numbers ...
positions = [[0, 0, 0]]  # as a list of triples x,y,z
system = molsturm.System(atoms, positions)
system.charge = 0  # Optional, 0 by default
system.multiplicity = 1  # Optional, 1 by default for even-electron systems,
#                                    2 for odd-electron systems
params.system = system

# Supply basis set information
basis = molsturm.construct_basis("gaussian", system, basis_set_name="pc-3")
# basis = molsturm.construct_basis("sturmian/atomic", system, k_exp=1.988,
#                                  n_max=5, l_max=1, m_max=1)
params.basis = basis

# Compute integral data
print("Computing integrals ... ", end="", flush=True)
s_bb = integrals.overlap_bb(params)
t_bb = integrals.kinetic_bb(params)
v_bb = integrals.nuclear_attraction_bb(params)
eri_bbbb = integrals.electron_repulsion_bbbb(params)
print("done")
Ejemplo n.º 16
0
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with molsturm. If not, see <http://www.gnu.org/licenses/>.
##
## ---------------------------------------------------------------------

import molsturm
import molsturm.sturmian

l_max = 1
n_max = 5

for atom, mult in [("He", 1), ("Be", 1), ("C", 3), ("Ne", 1)]:
    system = molsturm.System(atom)
    system.multiplicity = mult

    scfparams = molsturm.ScfParameters()
    scfparams.system = system

    k_guess = molsturm.sturmian.cs.empirical_kopt(scfparams.system)
    scfparams.basis = molsturm.construct_basis("sturmian/atomic/cs_reference_pc",
                                               scfparams.system, k_exp=k_guess,
                                               n_max=n_max, l_max=l_max)

    scfparams["scf/eigensolver/method"] = "lapack"
    scfparams["guess/eigensolver/method"] = "lapack"

    print("Running for " + atom + " please wait")
    best = molsturm.sturmian.cs.find_kopt(scfparams, print_iterations=True)