Exemple #1
0
 def set_new_node(self, k):
     new_coords = self.new_node_coords(k)
     new_node = Geometry(self.image_atoms, new_coords)
     new_node.set_calculator(self.calc_getter())
     self.images.insert(k+1, new_node)
     # print(f"made node {k+1}")
     return new_node
Exemple #2
0
def test_dimer(rotation_method, ref_cycle):
    coords = (-0.2, 1.1, 0)
    geom = Geometry(("X", ), coords)
    N_raw = np.array((0.83, 0.27, 0.))

    # New implementation
    dimer_kwargs = {
        "rotation_method": rotation_method,
        "calculator": AnaPot(),
        "N_raw": N_raw,
        "rotation_remove_trans": False,
    }
    dimer = Dimer(**dimer_kwargs)
    geom.set_calculator(dimer)

    opt_kwargs = {
        "precon": False,
        "line_search": None,
        "max_step_element": 0.25,
        "thresh": "gau_tight",
        "max_cycles": 15,
    }
    opt = PreconLBFGS(geom, **opt_kwargs)
    opt.run()
    # AnaPot().plot_opt(opt)

    assert opt.is_converged
    assert opt.cur_cycle == ref_cycle
    assert geom.energy == pytest.approx(2.80910484)
def prepare_opt():
    ethan_xyz = "xyz_files/ethan.xyz"
    atoms, coords = parse_xyz_file(ethan_xyz)
    geom = Geometry(atoms, coords.flatten())
    geom.set_calculator(ORCA())
    
    return geom, copy.copy(KWARGS)
Exemple #4
0
 def write_fragment_geoms(self, atoms, coords):
     geom = Geometry(atoms, coords)
     for i, frag in enumerate(self.fragment_indices):
         frag_geom = geom.get_subgeom(frag)
         fn = f"frag_geom_{i:02d}.xyz"
         with open(fn, "w") as handle:
             handle.write(frag_geom.as_xyz())
         self.log(f"Wrote geometry of fragment {i:02d} to {fn}.")
Exemple #5
0
def get_dimer_ends(geom0, N, R, calc_getter):
    dummy_coords = np.zeros_like(geom0.coords)
    geom1 = Geometry(geom0.atoms, dummy_coords)
    geom2 = Geometry(geom0.atoms, dummy_coords)
    update_dimer_ends(geom0, geom1, geom2, N, R)
    geom1.set_calculator(calc_getter())

    return geom1, geom2
 def get_new_image_from_coords(self, coords, index):
     new_image = Geometry(
         self.image_atoms,
         coords,
         coord_type=self.coord_type,
         coord_kwargs={
             "prim_indices": self.prim_indices,
         },
     )
     new_image.set_calculator(self.calc_getter())
     self.images.insert(index, new_image)
     self.log(f"Create new image; insert it before index {index}.")
     return new_image
def prepare_geometry(xyz_fn, keywords):

    #blocks = "%pal nprocs 3 end"
    blocks = ""

    atoms, coords = parse_xyz_file(THIS_DIR / xyz_fn)
    coords *= ANG2BOHR
    geometry = Geometry(atoms, coords.flatten())

    geometry.set_calculator(ORCA(keywords, charge=0, mult=1, blocks=blocks))

    hessian = geometry.hessian
    return geometry
def prepare_geometry():
    keywords = "HF 4-22GSP TightSCF"
    xyz_fn = "01_irc_sn2_fluour_transfer_optts.xyz"
    #blocks = "%pal nprocs 3 end"
    blocks = ""

    atoms, coords = parse_xyz_file(THIS_DIR / xyz_fn)
    coords *= ANG2BOHR
    geometry = Geometry(atoms, coords.flatten())

    geometry.set_calculator(ORCA(keywords, charge=-1, mult=1, blocks=blocks))

    hessian = geometry.hessian
    return geometry, THIS_DIR
Exemple #9
0
    def interpolate(self, initial_geom, final_geom):
        print(f"No. of primitives at initial structure: {initial_geom.coords.size}")
        print(f"No. of primitives at final structure: {final_geom.coords.size}")

        typed_prims = form_coordinate_union(initial_geom, final_geom)
        print("Union of primitives: ", len(typed_prims))

        geom1 = Geometry(initial_geom.atoms, initial_geom.cart_coords,
                         coord_type="redund",
                         coord_kwargs={"typed_prims": typed_prims,},
        )
        geom2 = Geometry(final_geom.atoms, final_geom.cart_coords,
                         coord_type="redund",
                         coord_kwargs={"typed_prims": typed_prims,},
        )

        dihed_start = geom1.internal.dihed_start
        initial_tangent = get_tangent(geom1.coords, geom2.coords, dihed_start)
        initial_diff = np.linalg.norm(initial_tangent)
        approx_stepsize = initial_diff / (self.between+1)
        final_prims = geom2.internal.prim_coords

        geoms = [geom1, ]
        for i in range(self.between):
            print(f"Interpolating {i+1:03d}/{self.between:03d}")
            new_geom = geoms[-1].copy()
            prim_tangent = get_tangent(new_geom.coords, final_prims, dihed_start)
            # Form active set
            B = new_geom.internal.B_prim
            G = B.dot(B.T)
            eigvals, eigvectors = np.linalg.eigh(G)
            U = eigvectors[:, np.abs(eigvals) > 1e-6]
            reduced_tangent = (np.einsum("i,ij->j", prim_tangent, U) * U).sum(axis=1)
            reduced_tangent /= np.linalg.norm(reduced_tangent)
            step = approx_stepsize * reduced_tangent
            try:
                new_coords = new_geom.coords + step
            except ValueError as err:
                fn = "redund_interpol_fail.trj"
                write_geoms_to_trj(geoms, fn)
                print(f"Chosen set of primitives is not valid for step {i} "
                      f"of {self.between}. Wrote interpolation progress to "
                       "'{fn}'."
                )
                raise err

            new_geom.coords = new_coords
            geoms.append(new_geom)
        return geoms[1:]
Exemple #10
0
def test_sqnm_bio_mode():
    atoms = "h h".split()
    coords = ((0, 0, 0), (0, 0, 1))
    geom = Geometry(atoms, coords)
    xtb = XTB()
    geom.set_calculator(xtb)

    opt = StabilizedQNMethod(geom)
    cur_grad = geom.gradient
    stretch_grad, rem_grad = opt.bio_mode(cur_grad)
    # There is only one bond in H2, so stretch_gradient == cur_grad and the
    # remainder should be the zero vector.
    np.testing.assert_allclose(stretch_grad, cur_grad)
    np.testing.assert_allclose(np.linalg.norm(rem_grad), 0.)
    return
def test_lennard_jones():
    atoms = Icosahedron("Ar", noshells=2, latticeconstant=3)
    atoms.set_calculator(ase_LJ())
    ase_forces = atoms.get_forces()
    ase_energy = atoms.get_potential_energy()

    coords = atoms.positions.flatten()
    geom = Geometry(atoms.get_chemical_symbols(), coords / BOHR2ANG)
    geom.set_calculator(LennardJones())

    pysis_energy = geom.energy
    assert pysis_energy == pytest.approx(ase_energy)

    pysis_forces = geom.forces / BOHR2ANG
    np.testing.assert_allclose(pysis_forces, ase_forces.flatten(), atol=1e-15)
Exemple #12
0
def get_geoms(coords=None):
    if coords is None:
        # left = np.array((0.188646, 1.45698, 0))
        # right = np.array((0.950829, 1.54153, 0))
        left = np.array((0.354902, 1.34229, 0))
        right = np.array((0.881002, 1.71074, 0))
        right = np.array((0.77, 1.97, 0))

        # Very close
        # left = np.array((0.531642, 1.41899, 0))
        # right = np.array((0.702108, 1.57077, 0))
        coords = (right, left)

        # near_ts = np.array((0.553726, 1.45458, 0))
        # coords = (near_ts, )

        # left_far = np.array((-0.455116, 0.926978, 0))
        # right_far = np.array((-0.185653, 1.02486, 0))
        # coords = (left_far, right_far)

    atoms = ("H")
    geoms = [Geometry(atoms, c) for c in coords]
    for geom in geoms:
        geom.set_calculator(AnaPot())
    return geoms
Exemple #13
0
def get_geoms():
    initial = np.array((-0.5, 0.5, 0))
    final = np.array((0.5, 0.5, 0))
    coords = (initial, final)
    atoms = ("H")
    geoms = [Geometry(atoms, c) for c in coords]
    return geoms
Exemple #14
0
def print_internals(geoms, filter_atoms=None, add_prims=""):
    if filter_atoms is None:
        filter_atoms = set()

    filter_set = set(filter_atoms)
    pi_types = {2: "B", 3: "A", 4: "D"}
    add_prims = yaml.safe_load(add_prims)

    for i, geom in enumerate(geoms):
        print(geom)
        atom_num = len(geom.atoms)
        atom_inds = set(range(atom_num))
        # Atom indices must superset of filter_atoms
        invalid = filter_set - atom_inds
        assert not invalid, \
            f"Filter indices {invalid} are outside of the " \
            f"valid range for the {i}-th geometry '{geom}' with {atom_num} " \
            f"atoms (valid indices: range(0,{atom_num}))."

        int_geom = Geometry(
            geom.atoms,
            geom.coords,
            coord_type="redund",
            coord_kwargs={
                "define_prims": add_prims,
            },
        )

        prim_counter = 0
        prev_len = 2
        for j, pi in enumerate(int_geom.internal._prim_internals):
            pi_type = pi_types[len(pi.inds)]
            val = pi.val
            len_ = len(pi.inds)
            if len_ > 2:
                unit = "°"
                val = np.rad2deg(val)
            else:
                val *= BOHR2ANG
                unit = " Å"

            if len_ > prev_len:
                prim_counter = 0
                print()

            # Continue if we want to filter and there is no intersection
            # between the atoms of the current primitive and the atoms we
            # want to filter for.
            if filter_set and not (set(pi.inds) & filter_set):
                continue
            print(
                f"{j:04d}: {pi_type}{prim_counter:03d}{str(pi.inds): >20} {val: >10.4f}"
                f"{unit}")
            prim_counter += 1
            prev_len = len_

        print(f"Printed {j+1} primitive internals.")
        print()
Exemple #15
0
def test_lj_external_potential():
    atoms = ("X", )
    coords = (0., 0., 0.)
    geom = Geometry(atoms, coords)

    calc = LennardJones()
    geom.set_calculator(calc)

    ref_energy = geom.energy
    potentials = [
        {
            "type": "logfermi",
            "beta": 6,
            "T": 300,
            "radius": 8,
        },
    ]
    ext_calc = ExternalPotential(calc, potentials=potentials)
    geom.set_calculator(ext_calc)
    ext_energy = geom.energy
    assert ext_energy == pytest.approx(ref_energy)

    displ_coords = (9., 0., 0)
    geom.coords = displ_coords
    ext_energy = geom.energy
    assert ext_energy == pytest.approx(0.00570261)

    forces = geom.forces
    ref_forces = np.array((-0.0056861, 0., 0.))
    np.testing.assert_allclose(forces, ref_forces, atol=1e-6)
def prepare_geometry(keywords=None, xyz_fn=None):
    this_dir = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))

    if not keywords:
        keywords = "HF STO-3G TightSCF"
    if not xyz_fn:
        xyz_fn = "hfabstraction_sto3g_ts.xyz"
    #blocks = "%pal nprocs 3 end"
    blocks = ""

    atoms, coords = parse_xyz_file(this_dir / xyz_fn)
    coords *= ANG2BOHR
    geometry = Geometry(atoms, coords.flatten())

    geometry.set_calculator(ORCA(keywords, charge=0, mult=1, blocks=blocks))

    hessian = geometry.hessian
    return geometry, this_dir
 def interpolate_between(self, initial_ind, final_ind, image_num):
     initial_coords = self.images[initial_ind].coords
     final_coords = self.images[final_ind].coords
     step = (final_coords - initial_coords) / (image_num + 1)
     # initial + i*step
     i_array = np.arange(1, image_num + 1)
     atoms = self.images[0].atoms
     new_coords = initial_coords + i_array[:, None] * step
     return [Geometry(atoms, nc) for nc in new_coords]
    def set_new_frontier_nodes(self):
        tangent = self.get_tangent()
        new_left_coords = self.left_frontier.coords + tangent*self.step_length
        new_left_frontier = Geometry(self.atoms, new_left_coords)
        new_left_frontier.set_calculator(self.calc_getter())
        self.left_string.append(new_left_frontier)

        new_right_coords = self.right_frontier.coords - tangent*self.step_length
        new_right_frontier = Geometry(self.atoms, new_right_coords)
        new_right_frontier.set_calculator(self.calc_getter())
        self.right_string.insert(0, new_right_frontier)
Exemple #19
0
    def interpolate(self, initial_geom, final_geom):
        initial_coords = initial_geom.coords
        final_coords = final_geom.coords

        # Linear interpolation
        step = (final_coords - initial_coords) / (self.between + 1)
        # initial + i*step
        i_array = np.arange(1, self.between + 1)
        new_coords = initial_coords + i_array[:, None] * step
        return [Geometry(self.atoms, nc) for nc in new_coords]
Exemple #20
0
def test_rfoptimizer():
    kwargs = {
        #"max_cycles": 10,
        "trust_radius": 0.5,
        "max_step": 0.5,
    }
    atoms = ("X", )
    # http://www.applied-mathematics.net/optimization/optimizationIntro.html
    coords = (0.7, -3.3, 0)
    geom = Geometry(atoms, coords)
    ap4 = AnaPot4()
    geom.set_calculator(ap4)
    opt = RFOptimizer(geom, **kwargs)
    #opt = SteepestDescent(geom, **kwargs)
    #opt = BFGS(geom, max_step=1.0)
    opt.run()
    rfop = RFOPlotter(ap4, opt, save=True, title=False)
    rfop.plot()
    plt.show()
Exemple #21
0
def run_distributed(scheduler=None):

    init_logging(THIS_DIR, scheduler)
    atoms = ("H", "H")
    geoms = list()
    for i in range(7):
        bond_length = 0.8 + i * 0.2
        print(f"{i}: {bond_length:.02f}")
        coords = np.array((0., 0., 0., 0., 0., bond_length))
        geom = Geometry(atoms, coords)
        # def2-TZVP / TDDFT
        td_kwargs = {
            "keywords": "BP86 def2-TZVP",
            "charge": 0,
            "mult": 1,
            "calc_number": i,
            "blocks": "%tddft nroots 2 iroot 1 end",
            #"track": True,
            "out_dir": THIS_DIR,
        }
        # def2-SV(P) / Ground state
        kwargs = {
            "keywords": "BP86 def2-SV(P)",
            "charge": 0,
            "mult": 1,
            "calc_number": i,
            "out_dir": THIS_DIR,
        }
        orca = ORCA(**td_kwargs)
        geom.set_calculator(orca)
        geoms.append(geom)

    neb_kwargs = {
        "dask_cluster": scheduler,
    }
    neb = NEB(geoms, **neb_kwargs)
    forces = neb.forces
    for f in forces.reshape(-1, 6):
        print(f, f"{np.linalg.norm(f):.2f}")

    for geom in neb.images:
        print(geom.calculator.wfow)
Exemple #22
0
def get_hexagonal_geom(r=2, distort=False):
    phi = np.array((30, 90, 150, 210, 270, 330))
    x, y = pol2cart(2, phi)
    z = np.zeros_like(x)
    if distort:
        y[1] = 3

    atoms = "C" * x.size
    coords3d = np.stack((x, y, z), axis=1)
    geom = Geometry(atoms, coords3d.flatten())
    return geom
Exemple #23
0
def read_geoms(xyz_fns, in_bohr=False, coord_type="cart",
               define_prims=None, typed_prims=None):
    if isinstance(xyz_fns, str):
        xyz_fns = [xyz_fns, ]

    geoms = list()
    geom_kwargs = {
        "coord_type": coord_type,
    }
    # Dont supply coord_kwargs with coord_type == "cart"
    if coord_type != "cart":
        geom_kwargs["coord_kwargs"] = {
            "define_prims": define_prims,
            "typed_prims": typed_prims,
        }

    for fn in xyz_fns:
        if "*" in fn:
            cwd = Path(".")
            geom = [geom_loader(xyz_fn, **geom_kwargs)
                    for xyz_fn in natsorted(cwd.glob(fn))]
        # Simplify this to use geom_loader...
        elif fn.endswith(".xyz"):
            geom = [geom_loader(fn, **geom_kwargs), ]
        elif fn.endswith(".trj"):
            geom = geom_loader(fn, **geom_kwargs)
        elif fn.endswith(".pdb"):
            geom = [geom_loader(fn, **geom_kwargs), ]
        elif fn.endswith(".cjson"):
            geom = [geom_loader(fn, **geom_kwargs), ]
        else:
            continue
        geoms.extend(geom)

    # Try to parse as inline xyz formatted string
    if len(geoms) == 0:
        try:
            atoms_coords = split_xyz_str(fn)
            # We excpect the coordinates to be given in Angstrom
            geoms = [Geometry(atoms, coords/BOHR2ANG, **geom_kwargs)
                     for atoms, coords in atoms_coords]
        except AssertionError:
            raise Exception("Could not parse supplied 'xyz' values as either "
                            ".xyz, .trj or xyz-formatted string.!"
            )

    # Original coordinates are in bohr, but pysisyphus expects them
    # to be in Angstrom, so right now they are already multiplied
    # by ANG2BOHR. We revert this.
    if in_bohr:
        for geom in geoms:
            geom.coords *= BOHR2ANG
    return geoms
Exemple #24
0
def get_geoms(images=KWARGS["images"]):
    initial = "xyz_files/hcn.xyz"
    ts_guess = "xyz_files/hcn_iso_ts.xyz"
    final = "xyz_files/nhc.xyz"
    xyz_fns = (initial, ts_guess, final)
    atoms_coords = [parse_xyz_file(fn) for fn in xyz_fns]
    geoms = [
        Geometry(atoms, coords.flatten()) for atoms, coords in atoms_coords
    ]
    geoms = idpp_interpolate(geoms, images_between=images)

    return geoms, copy.copy(KWARGS)
Exemple #25
0
def test_lj_external_potential_opt():
    np.random.seed(20182503)

    radius = 9
    atom_num = 50
    coords3d = (np.random.rand(atom_num, 3) - 0.5) * 2 * radius
    atoms = ("Ar", ) * atom_num

    geom = Geometry(atoms, coords3d.flatten())

    lj_calc = LennardJones()
    geom.set_calculator(lj_calc)

    opt_kwargs = {
        "max_cycles": 250,
        "precon_update": 50,
        "c_stab": 0.5,
    }
    # opt = QuickMin(geom, **opt_kwargs)
    opt = PreconLBFGS(geom, **opt_kwargs)
    opt.run()
Exemple #26
0
def frag_sort(geoms):
    sorted_geoms = list()
    for i, geom in enumerate(geoms):
        print(f"{i:02d}: {geom}")
        frags = get_fragments(geom.atoms, geom.coords)
        print(f"\tFound {len(frags)} fragments.\n"
              "\tResorting atoms and coordinates.")
        new_indices = list(it.chain(*frags))
        new_atoms = [geom.atoms[i] for i in new_indices]
        new_coords = geom.coords3d[new_indices]
        sorted_geoms.append(Geometry(new_atoms, new_coords))
    return sorted_geoms
def get_geoms(keys=("B", "C", "TSA", "A")):
    coords_dict = {
        "A": (-0.558, 1.442, 0),  # Minimum A
        "B": (0.6215, 0.02838, 0),  # Minimum B
        "C": (-0.05, 0.467, 0),  # Minimum C
        "AC": (-0.57, 0.8, 0),  # Between A and C
        "TSA": (-0.822, 0.624, 0)  # Saddle point A
    }
    coords = [np.array(coords_dict[k]) for k in keys]
    atoms = ("H")
    geoms = [Geometry(atoms, c) for c in coords]
    return geoms
def augment_bonds(geom, root=0, proj=False):
    assert geom.coord_type != "cart"
    log(logger, "Trying to augment bonds.")

    hessian = geom.cart_hessian
    try:
        energy = geom.energy
    except AttributeError:
        energy = None

    func = find_missing_bonds_by_projection if proj else find_missing_strong_bonds

    missing_bonds = func(geom, hessian, root=root)

    if missing_bonds:
        aux_bond_pt = PrimTypes.AUX_BOND
        missing_aux_bonds = [(aux_bond_pt, *mbond) for mbond in missing_bonds]
        print("\t@Missing bonds:", missing_bonds)
        new_geom = Geometry(
            geom.atoms,
            geom.cart_coords,
            coord_type=geom.coord_type,
            coord_kwargs={
                "define_prims": missing_aux_bonds,
            },
        )
        new_geom.set_calculator(geom.calculator)
        new_geom.energy = energy
        new_geom.cart_hessian = hessian
        return new_geom
    else:
        return geom
Exemple #29
0
 def get_geom(cls, coords, atoms=("X", ), V_str=None):
     geom = Geometry(atoms, coords)
     if V_str:
         geom.set_calculator(cls(V_str=V_str))
     else:
         geom.set_calculator(cls())
     return geom
Exemple #30
0
def cap(geom, high_frag):
    high_set = set(high_frag)
    ind_set = set(range(len(geom.atoms)))
    rest = ind_set - high_set

    # Determine bond(s) that connect high_frag with the rest
    # bonds, _, _ = geom.internal.prim_indices
    bonds = get_bond_sets(geom.atoms, geom.coords3d)
    bond_sets = [set(b) for b in bonds]

    # Find all bonds that involve one atom of model. These bonds
    # connect the model to the real geometry. We want to cap these
    # bonds.
    break_bonds = [b for b in bond_sets if len(b & high_set) == 1]

    # Put capping atoms at every bond to break.
    # The model fragment size corresponds to the length of the union of
    # the model set and the atoms in break_bonds.
    capped_frag = high_set.union(*break_bonds)
    capped_inds = list(sorted(capped_frag))

    # Index map between the new model geometry and the original indices
    # in the real geometry.
    atom_map = {
        model_ind: real_ind
        for real_ind, model_ind in zip(capped_inds, range(len(capped_inds)))
    }

    # g = 0.723886 # Gaussian16
    g = 0.709  # Paper g98-ONIOM-implementation
    c3d = geom.coords3d.copy()
    new_atoms = list(geom.atoms)
    link_maps = dict()
    for bb in break_bonds:
        to_cap = bb - high_set
        assert len(to_cap) == 1
        r1_ind = list(bb - to_cap)[0]
        r3_ind = tuple(to_cap)[0]
        r1 = c3d[r1_ind]
        r3 = c3d[r3_ind]
        r2 = r1 + g * (r3 - r1)
        c3d[r3_ind] = r2
        new_atoms[r3_ind] = "H"
        new_ind = np.sum(np.array(high_frag) < r3_ind)
        link_map = LinkMap(r1_ind=r1_ind, r3_ind=r3_ind, g=g)
        link_maps[new_ind] = link_map

    capped_atoms = [new_atoms[i] for i in capped_inds]
    capped_coords = c3d[capped_inds].flatten()
    capped_geom = Geometry(capped_atoms, capped_coords)

    return capped_geom, atom_map, link_maps