Exemple #1
0
def setup_combos():
    atoms = setup_atoms()

    # Fix linear combination of two bond lengths with atom indices 0-8 and
    # 0-6 with weighting coefficients 1.0 and -1.0 to the current value.
    # In other words, fulfil the following constraint:
    # 1.0 * atoms.get_distance(2, 1) + -1.0 * atoms.get_distance(2, 3) = const.
    bondcombo_def = [[2, 1, 1.0], [2, 3, -1.0]]
    target_bondcombo = get_bondcombo(atoms, bondcombo_def)

    # Fix linear combination of two angles
    # 1. * atoms.get_angle(7, 0, 8) + 1. * atoms.get_angle(7, 0, 6) = const.
    anglecombo_def = [[7, 0, 8, 1.], [7, 0, 6, 1]]
    target_anglecombo = get_anglecombo(atoms, anglecombo_def)

    # Fix linear combination of two dihedrals
    dihedralcombo_def = [[3, 2, 1, 4, 1.0], [2, 1, 0, 7, 1.0]]
    target_dihedralcombo = get_dihedralcombo(atoms, dihedralcombo_def)

    # Initialize constraint
    constr = FixInternals(bondcombos=[(target_bondcombo, bondcombo_def)],
                          anglecombos=[(target_anglecombo, anglecombo_def)],
                          dihedralcombos=[(target_dihedralcombo,
                                           dihedralcombo_def)],
                          epsilon=1e-10)
    print(constr)
    return (atoms, constr, bondcombo_def, target_bondcombo, anglecombo_def,
            target_anglecombo, dihedralcombo_def, target_dihedralcombo)
Exemple #2
0
def setup_fixinternals():
    atoms = setup_atoms()

    # Angles, Bonds, Dihedrals are built up with pairs of constraint
    # value and indices defining the constraint
    # Linear combinations of bond lengths are built up similarly with the
    # coefficients appended to the indices defining the constraint

    # Fix bond between atoms 1 and 2 to 1.4
    bond_def = [1, 2]
    target_bond = 1.4

    # Fix angle to whatever it was from the start
    angle_def = [6, 0, 1]
    target_angle = atoms.get_angle(*angle_def)

    # Fix this dihedral angle to whatever it was from the start
    dihedral_def = [6, 0, 1, 2]
    target_dihedral = atoms.get_dihedral(*dihedral_def)

    # Initialize constraint
    constr = FixInternals(bonds=[(target_bond, bond_def)],
                          angles_deg=[(target_angle, angle_def)],
                          dihedrals_deg=[(target_dihedral, dihedral_def)],
                          epsilon=1e-10)
    print(constr)
    return (atoms, constr, bond_def, target_bond, angle_def, target_angle,
            dihedral_def, target_dihedral)
Exemple #3
0
def evaluate_energy(angles: Union[List[float], np.ndarray],
                    atoms: Atoms,
                    dihedrals: List[DihedralInfo],
                    calc: Calculator,
                    relax: bool = True) -> float:
    """Compute the energy of a cysteine molecule given dihedral angles
    Args:
        angles: List of dihedral angles
        atoms: Structure to optimize
        dihedrals: Description of the dihedral angles
        calc: Calculator used to compute energy/gradients
        relax: Whether to relax the non-dihedral degrees of freedom
    Returns:
        - (float) energy of the structure
    """
    # Make a copy of the input
    atoms = atoms.copy()

    # Set the dihedral angles to desired settings
    dih_cnsts = []
    for a, di in zip(angles, dihedrals):
        atoms.set_dihedral(*di.chain, a, indices=di.group)

        # Define the constraints
        dih_cnsts.append((a, di.chain))

    # If not relaxed, just compute the energy
    if not relax:
        return calc.get_potential_energy(atoms)

    atoms.set_constraint()
    atoms.set_constraint(FixInternals(dihedrals_deg=dih_cnsts))

    return relax_structure(atoms, calc)[0]
Exemple #4
0
def _constrain_molecule(atoms, rattle=0.00001):
    """Helper function for place_and_preoptimize_adsorbates
    
    Args:
        atoms (ase.Atoms)   :   adsorbate molecule
        rattle (float)  : standard deviation of the structure rattling

    Returns:
        list :      list of different constraints from ase.constraints 
                    bonds, angles and dihedrals other than those of
                    sp3-centers are constrained
    """
    # Rattling is important, otherwise the optimization fails!
    atoms.rattle(stdev=rattle)

    nb_lst, nl = _get_neighbours(atoms, buffer_factor=1.5)
    fb = FixBondLengths(nb_lst)
    fa = _fix_nearest_atom_to_x(atoms, nl)

    angles = _get_all_angles(atoms, nb_lst)
    dihedrals = _get_all_dihedrals(atoms, angles)
    # keep dihedrals with sp2 or sp center
    # use neighbor list and a custom dictionary for number of nearest neighbors
    dihedrals = _filter_dihedrals(atoms, nl, dihedrals)
    print("kept dhls", dihedrals)

    fi = FixInternals(angles= angles, dihedrals = dihedrals)

    hookean_lst = _hookean_bonds(atoms, nb_lst)

    # IMPORTANT! fix binding atom at the end, otherwise it moves!
    atoms.set_constraint(hookean_lst.extend([fi, fb, fa]))
    return atoms
Exemple #5
0
	def adjust_z_axis(self, cluster):
		if self.surface == None:
			return
		'''
		surface_constraints = []
		for atom in self.surface:
			surface_constraints.append(MyConstraint(atom.index,(0,0,1)))
		'''
		surface_constraints = []
		#surface_constraints.append(ExternalForce(0, 0, 10))
		all_bonds = []
		all_angles = []
		all_dihedrals = []
		for index_1 in range(len(self.surface)):
			for index_2 in range(index_1+1,len(self.surface)):
				bonds_distance = get_distance(self.surface[index_1],self.surface[index_2])
				bond = [bonds_distance, [index_1,index_2]]
				all_bonds.append(bond)
				"""
				for index_3 in range(index_2+1,len(self.surface)): 
					angle_indices = [[index_1,index_2,index_3],[index_3,index_1,index_2],[index_2,index_3,index_1]]
					for angle_indice in angle_indices:
						angle = [self.surface.get_angle(*angle_indice) * pi / 180, angle_indice]
						all_angles.append(angle)
					'''
					for index_4 in range(index_3+1,len(self.surface)):  
						dihedral_indices = [[index_1,index_2,index_3,index_4],[index_1,index_2,index_3,index_4],[index_1,index_2,index_3,index_4]]
						for dihedral_indice in dihedral_indices:
							dihedral = [self.surface.get_dihedral(*dihedral_indice) * pi / 180, dihedral_indice]
							all_dihedrals.append(dihedral)
					'''
				"""
		surface_constraints.append(FixInternals(bonds=all_bonds, angles=all_angles, dihedrals=all_dihedrals))
		#self.surface.set_constraint(surface_constraints)

		c = FixAtoms(indices=range(len(self.surface),len(self.surface)+len(cluster)))
		cluster_constraints = [c]
		#cluster.set_constraint(cluster_constraints)

		for atom in self.surface:
			atom.z -= 40.0

		system = self.surface + cluster
		system.set_calculator(EMT())
		system.set_constraint(surface_constraints+cluster_constraints)
		dyn = FIRE(system)
		converged = False
		import pdb; pdb.set_trace()
		try:
			dyn.run(fmax=0.01,steps=5000)
			converged = dyn.converged()
			if not converged:
				import os
				name = os.path.basename(os.getcwd())
				errorMessage = 'The optimisation of cluster ' + name + ' did not optimise completely.'
				print(errorMessage, file=sys.stderr)
				print(errorMessage)
		except:
			print('Local Optimiser Failed for some reason.')
		import pdb; pdb.set_trace()
 def __init__(self, repeat):
     nmol = repeat[0] * repeat[1] * repeat[2]
     r = rOH
     a = angleHOH * pi / 180
     # From https://doi.org/10.1063/1.445869
     eexp = 6.24 * units.kcal / units.mol
     dexp = 2.75
     aexp = 46
     D = np.linspace(2.5, 3.5, 30)
     x = angleHOH * np.pi / 180 / 2
     pos = [[0, 0, 0], [0, rOH * np.cos(x), rOH * np.sin(x)],
            [0, rOH * np.cos(x), -rOH * np.sin(x)]]
     calc = TIP4P()
     self.h2o = Atoms('OH2', [(0, 0, 0), (r * cos(a), 0, r * sin(a)),
                              (r, 0, 0)])
     vol = ((18.01528 / 6.022140857e23) / (0.9982 / 1e24))**(1 / 3.)
     self.h2o.set_cell((1.1 * r, 1.1 * r, 1.1 * r))
     self.h2o = self.h2o.repeat(repeat)
     self.h2o.set_cell((0, 0, 0))
     nmol = int(self.h2o.positions.shape[0] / 3)
     bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
     for i in range(nmol):
         bonds.append((3 * i, 3 * i + 2))
     bonds_rOH = []
     for bond in bonds:
         bonds_rOH.append((rOH, (bond)))
     angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
     self.h2o.constraints = FixInternals(bonds=bonds_rOH,
                                         angles=angles,
                                         epsilon=epsilon0)
     calc = TIP4P()
     self.h2o.calc = calc
Exemple #7
0
    def opt(self, rdkmol, dhls, logger='optlog.out'):
        Na = rdkmol.GetNumAtoms()
        X, S = __convert_rdkitmol_to_nparr__(rdkmol)
        atm=Atoms(symbols=S, positions=X)
        atm.set_calculator(ANIENS(self.ens))                #Set the ANI Ensemble as the calculator

        phi_fix = []
        for d in dhls:
            phi_restraint=atm.get_dihedral(d)
            phi_fix.append([phi_restraint, d])
        c = FixInternals(dihedrals=phi_fix, epsilon=1.e-9)
        atm.set_constraint(c)

        dyn = LBFGS(atm, logfile=logger)                               #Choose optimization algorith
        dyn.run(fmax=self.fmax, steps=1000)         #optimize molecule to Gaussian's Opt=Tight fmax criteria, input in eV/A (I think)
        e=atm.get_potential_energy()*hdt.evtokcal
        s=atm.calc.stddev*hdt.evtokcal
        
        phi_value = []
        for d in dhls:
            phi_value.append(atm.get_dihedral(d)*180./np.pi)
        #X = mol.get_positions()
        if self.printer: 
            print('Phi value (degrees), energy (kcal/mol), sigma= ', phi_value, "{0:.2f}".format(e), "{0:.2f}".format(s))
        return phi_value, e, s, atm
def add_tip4p_const(water):
    nmol = int(water.positions.shape[0] / 3)
    a = angleHOH * pi / 180
    bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
    for i in range(nmol):
        bonds.append((3 * i, 3 * i + 2))
    bonds_rOH = []
    for bond in bonds:
        bonds_rOH.append((rOH, (bond)))
    angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
    water.constraints = FixInternals(bonds=bonds_rOH,
                                     angles=angles,
                                     epsilon=epsilon0)
    calc = TIP4P()
    water.calc = calc
    return water
def PreventScramblingConstraint(graph,
                                atoms,
                                double_bond_protection=False,
                                fix_angles=False):
    '''
    graph: NetworkX graph of the molecule
    atoms: ASE atoms object

    return: FixInternals constraint to apply to ASE calculations
    '''
    angles_deg = None
    if fix_angles:
        allpaths = []

        for node in graph:
            allpaths.extend(findPaths(graph, node, 2))

        allpaths = {tuple(sorted(path)) for path in allpaths}

        angles_deg = []
        for path in allpaths:
            angles_deg.append([atoms.get_angle(*path), list(path)])

    bonds = []
    for bond in [[a, b] for a, b in graph.edges if a != b]:
        bonds.append([atoms.get_distance(*bond), bond])

    dihedrals_deg = None
    if double_bond_protection:
        double_bonds = get_double_bonds_indexes(atoms.positions,
                                                atoms.get_atomic_numbers())
        if double_bonds != []:
            dihedrals_deg = []
            for a, b in double_bonds:
                n_a = neighbors(graph, a)
                n_a.remove(b)

                n_b = neighbors(graph, b)
                n_b.remove(a)

                d = [n_a[0], a, b, n_b[0]]
                dihedrals_deg.append([atoms.get_dihedral(*d), d])

    return FixInternals(dihedrals_deg=dihedrals_deg,
                        angles_deg=angles_deg,
                        bonds=bonds,
                        epsilon=1)
Exemple #10
0
def _copy_and_set_constraints(atoms, n_atoms_per_molecule, rigid_atoms, 
    bonds, angles, dihedrals, hookean_lst):
    """Helper function for place_and_preoptimize_adsorbates
    
    Args:
        atoms (ase.Atoms)   :   conglomerate of adsorbate molecules
        n_atoms_per_molecule (int)  : number of atoms per single molecule
        rigid_atoms (list)  :   indices of atoms to be fixed
        bonds (list)        :   each element contains a tuple of bondlength and atom indices
        angles (list)       :   each element contains a tuple of angle and atom indices
        dihedrals (list)    :   each element contains a tuple of dihedral and atom indices
        hookean_lst (list)  :   ase.constraints.Hookean bond constraints

    Returns:
        tuple :     All indices of rigid_atoms, bonds, angles, dihedrals and hookean_lst are
                    shifted by shift
    """
    n_adsorbates = int(len(atoms) / n_atoms_per_molecule)

    all_rigid_atoms = []
    all_bonds = []
    all_hookeans = []
    all_angles = []
    all_dihedrals = []
    for i in range(n_adsorbates):
        shift = i * n_atoms_per_molecule
        new_rigid_atoms, new_bonds, new_angles, new_dihedrals, new_hookean_lst = _shift_constraints(shift,
            rigid_atoms, bonds, angles, dihedrals, hookean_lst)
        all_rigid_atoms.extend(new_rigid_atoms)
        all_bonds.extend(new_bonds)
        all_angles.extend(new_angles)
        all_dihedrals.extend(new_dihedrals)
        all_hookeans.extend(new_hookean_lst)

    # too heavy!!!
    #fi = FixInternals(angles=all_angles, dihedrals=all_dihedrals, bonds=all_bonds, epsilon=1e-7)
    fi = FixInternals(angles=angles, dihedrals=dihedrals, bonds=bonds, epsilon=1e-7)

    fa = FixAtoms(all_rigid_atoms)

    # IMPORTANT! fix binding atom at the end, otherwise it moves!
    #atoms.set_constraint(hookean_lst.extend([fi, fa]))
    atoms.set_constraint([fi, fa])
    return atoms
def test_getindices():
    from ase.build import fcc111
    from ase.constraints import (FixAtoms, FixBondLengths, FixLinearTriatomic,
                                 FixInternals, Hookean, constrained_indices)

    slab = fcc111('Pt', (4, 4, 4))

    C1 = FixAtoms([0, 2, 4])
    C2 = FixBondLengths([[0, 1], [0, 2]])
    C3 = FixInternals(bonds=[[1, [7, 8]], [1, [8, 9]]])
    C4 = Hookean(a1=30, a2=40, rt=1.79, k=5.)
    C5 = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)])

    slab.set_constraint([C1, C2, C3, C4, C5])
    assert all(
        constrained_indices(slab, (FixAtoms, FixBondLengths)) == [0, 1, 2, 4])
    assert all(
        constrained_indices(slab, (FixBondLengths,
                                   FixLinearTriatomic)) == [0, 1, 2, 3, 4, 5])
    assert all(
        constrained_indices(slab) == [0, 1, 2, 3, 4, 5, 7, 8, 9, 30, 40])
Exemple #12
0
    def __init__(self, nmol=5, size=3):
        r = rSH
        a = angleHSH * pi / 180

        # From https://doi.org/10.1063/1.445869
        eexp = 6.24 * units.kcal / units.mol
        dexp = 2.75
        aexp = 46
        D = np.linspace(2.5, 3.5, 30)
        x = angleHSH * np.pi / 180 / 2

        pos = [[0.00000000, 0.00000000, 0.10357400],
               [0.00000000, 0.97644400, -0.82858900],
               [0.00000000, -0.97644400, -0.82858900]]
        pos = pos * nmol
        calc = H2S()
        self.h2o = Atoms('SH2' * nmol, pos)
        disp = np.random.uniform(-size, size, (nmol, 3))
        final_dis = []
        for i in range(nmol):
            d = disp[i].tolist()
            for i in range(3):
                final_dis.append(d)

        self.h2o.set_positions(pos + np.array(final_dis))
        #vol = ((18.01528 / 6.022140857e23) / (0.9982 / 1e24))**(1 / 3.)
        #self.h2o.set_cell((1.1*r , 1.1*r , 1.1*r ))
        #nmol = int(self.h2o.positions.shape[0] / 3)
        bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
        for i in range(nmol):
            bonds.append((3 * i, 3 * i + 2))
        bonds_rSH = []
        for bond in bonds:
            bonds_rSH.append((rSH, (bond)))
        angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
        self.h2o.constraints = FixInternals(bonds=bonds_rSH,
                                            angles=angles,
                                            epsilon=epsilon0)
        calc = H2S()
        self.h2o.calc = calc
def set_dihedrals_and_relax(atoms: Atoms, dihedrals: List[Tuple[float, DihedralInfo]]) -> float:
    """Set the dihedral angles and compute the energy of the system
    
    Args:
        atoms: Molecule to ajdust
        dihedrals: List of dihedrals to set to a certain angle
    Returns:
        Energy of the system
    """
    
    # Copy input so that we can loop over it twice (i.e., avoiding problems around zip being a generator)
    dihedrals = list(dihedrals)
    
    # Set the dihedral angles to desired settings
    for di in dihedrals:
        atoms.set_dihedral(*di[1].chain, di[0], indices=di[1].group)
        
    # Define the constraints
    dih_cnsts = [(di[0], di[1].chain) for di in dihedrals]
    atoms.set_constraint()
    atoms.set_constraint(FixInternals(dihedrals_deg=dih_cnsts))
    
    return relax_structure(atoms)
Exemple #14
0
        def iterate(atoms : Atoms):
            delta = 0.01
            global bond1
            global bond2
            force = atoms.get_forces()[i['DIFFATOM']]
            bond1_dist   = atoms.get_distance(i['DIFFATOM'], i['CONSATOM1'], vector=False)
            bond1_vector = atoms.get_distance(i['DIFFATOM'], i['CONSATOM1'], vector=True )
            bond1_unit = bond1_vector / bond1_dist
            bond2_dist   = atoms.get_distance(i['DIFFATOM'], i['CONSATOM2'], vector=False)
            bond2_vector = atoms.get_distance(i['DIFFATOM'], i['CONSATOM2'], vector=True )
            bond2_unit = bond2_vector / bond2_dist

            bond1_projection = np.dot(force, bond1_unit)
            bond2_projection = np.dot(force, bond2_unit)
            if abs(bond1_projection) > bond2_projection:
                if bond1_projection > 0:
                    print('Growing Bond 1')
                    bond1 += delta
                    bond2 -= delta / 4
                else:
                    print('Shrinking Bond 1')
                    bond1 -= delta
                    bond2 += delta / 4
            else:
                if bond2_projection > 0:
                    print('Growing Bond 2')
                    bond2 += delta
                    bond1 -= delta / 4
                else:
                    print('Shrinking Bond 2')
                    bond2 -= delta
                    bond1 += delta / 4
            bonds = [
                [ bond1, [ i['DIFFATOM'], i['CONSATOM1'] ] ],
                [ bond2, [ i['DIFFATOM'], i['CONSATOM2'] ] ]
                    ]
            return FixInternals(bonds=bonds)
Exemple #15
0
    F = []
    for d in D:
        dimer.positions[3:, 0] += d - dimer.positions[3, 0]
        E.append(dimer.get_potential_energy())
        F.append(dimer.get_forces())

    F = np.array(F)

    #plt.plot(D, E)

    F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D)
    F2 = F[:, :3, 0].sum(1)
    error = abs(F1 - F2).max()

    dimer.constraints = FixInternals(bonds=[(r, (0, 1)), (r, (0, 2)),
                                            (r, (3, 4)), (r, (3, 5))],
                                     angles=[(a, (2, 0, 1)), (a, (5, 3, 4))])
    opt = BFGS(dimer,
               trajectory=calc.name + '.traj',
               logfile=calc.name + 'd.log')
    opt.run(0.01)

    e0 = dimer.get_potential_energy()
    d0 = dimer.get_distance(0, 3)
    R = dimer.positions
    v1 = R[2] - R[3]
    v2 = R[3] - (R[5] + R[4]) / 2
    a0 = np.arccos(np.dot(v1, v2) /
                   (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180
    fmt = '{0:>23}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}'
    print(fmt.format(calc.name, -min(E), -e0, d0, a0))
Exemple #16
0
b1 = [1.4, b1_ind]
bond_list.append(b1)
b1_ind = [3, 2]
b1 = [1.26, b1_ind]
bond_list.append(b1)
b1_ind = [2, 0]
b1 = [1.4, b1_ind]
bond_list.append(b1)

angle_list = []

#angle_ind = [3,2,0]
#angle = [atoms.get_angle(angle_ind), angle_ind]
#angle_list.append(angle)

c = FixInternals(atoms, bonds=bond_list, angles=angle_list)
#c = FixInternals(atoms, bonds=[b1, b2, b3], angles=[])

atoms.set_constraint(c)

atoms.set_angle(indices2, (ang2 / 180.) * np.pi, mask=mask2)
atoms.set_angle(indices3, (ang3 / 180.) * np.pi, mask=mask3)
atoms.set_dihedral(indices1, (ang1 / 180.) * np.pi, mask=mask1)

atoms.set_calculator(calc)

omega = (atoms.get_dihedral(indices1) / np.pi) * 180.
alpha = (atoms.get_angle(indices2) / np.pi) * 180.
alpha2 = (atoms.get_angle(indices3) / np.pi) * 180.

print omega, alpha, alpha2
Exemple #17
0
# Fix this dihedral angle to whatever it was from the start
indices = [6, 0, 1, 2]
dihedral1 = system.get_dihedral(indices)

# Fix angle to whatever it was from the start
indices2 = [6, 0, 1]
angle1 = system.get_angle(indices2)
#system.set_dihedral(indices, pi/20, mask=[0,1,1,1,1,1,0,0,0])

# Fix bond between atoms 1 and 2 to 1.4
target_bondlength = 1.4
indices_bondlength = [1, 2]

constraint = FixInternals(bonds=[(target_bondlength, indices_bondlength)],
                          angles=[(angle1, indices2)],
                          dihedrals=[(dihedral1, indices)],
                          epsilon=1e-10)

print(constraint)

calc = EMT()

opt = BFGS(system, trajectory='opt.traj', logfile='opt.log')

previous_angle = system.get_angle(indices2)
previous_dihedral = system.get_dihedral(indices)

print('angle before', previous_angle)
print('dihedral before', previous_dihedral)
print('bond length before', system.get_distance(*indices_bondlength))
print('(target bondlength %s)', target_bondlength)
def test_turbomole_qmmm():
    """Test the Turbomole calculator in simple QMMM and
    explicit interaction QMMM simulations."""

    r = rOH
    a = angleHOH * pi / 180
    D = np.linspace(2.5, 3.5, 30)

    interaction = LJInteractions({('O', 'O'): (epsilon0, sigma0)})
    qm_par = {'esp fit': 'kollman', 'multiplicity': 1}

    for calc in [
            TIP3P(),
            SimpleQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), TIP3P()),
            SimpleQMMM([0, 1, 2],
                       Turbomole(**qm_par),
                       TIP3P(),
                       TIP3P(),
                       vacuum=3.0),
            EIQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), interaction),
            EIQMMM([3, 4, 5],
                   Turbomole(**qm_par),
                   TIP3P(),
                   interaction,
                   vacuum=3.0),
            EIQMMM([0, 1, 2],
                   Turbomole(**qm_par),
                   TIP3P(),
                   interaction,
                   vacuum=3.0)
    ]:
        dimer = Atoms('H2OH2O',
                      [(r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0),
                       (r * cos(a / 2), r * sin(a / 2), 0),
                       (r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0)])
        dimer.calc = calc

        E = []
        F = []
        for d in D:
            dimer.positions[3:, 0] += d - dimer.positions[5, 0]
            E.append(dimer.get_potential_energy())
            F.append(dimer.get_forces())

        F = np.array(F)

        F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D)
        F2 = F[:, :3, 0].sum(1)
        error = abs(F1 - F2).max()
        assert error < 0.9

        dimer.set_constraint(
            FixInternals(bonds=[(r, (0, 2)), (r, (1, 2)), (r, (3, 5)),
                                (r, (4, 5))],
                         angles_deg=[(angleHOH, (0, 2, 1)),
                                     (angleHOH, (3, 5, 4))]))
        opt = BFGS(dimer,
                   trajectory=calc.name + '.traj',
                   logfile=calc.name + 'd.log')
        opt.run(0.01)

        e0 = dimer.get_potential_energy()
        d0 = dimer.get_distance(2, 5)
        R = dimer.positions
        v1 = R[1] - R[5]
        v2 = R[5] - (R[3] + R[4]) / 2
        a0 = np.arccos(
            np.dot(v1, v2) /
            (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180
        fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}'
        print(fmt.format(calc.name, -min(E), -e0, d0, a0))
Exemple #19
0
from ase.build import fcc111
from ase.constraints import (FixAtoms, FixBondLengths, FixInternals, Hookean,
                             constrained_indices)

slab = fcc111('Pt', (4, 4, 4))

C1 = FixAtoms([0, 2, 4])
C2 = FixBondLengths([[0, 1], [0, 2]])
C3 = FixInternals(bonds=[[1, [7, 8]], [1, [8, 9]]])
C4 = Hookean(a1=30, a2=40, rt=1.79, k=5.)

slab.set_constraint([C1, C2, C3, C4])
assert all(
    constrained_indices(slab, (FixAtoms, FixBondLengths)) == [0, 1, 2, 4])
assert all(constrained_indices(slab) == [0, 1, 2, 4, 7, 8, 9, 30, 40])
def test_dihedralconstraint():
    from ase.calculators.emt import EMT
    from ase.constraints import FixInternals
    from ase.optimize.bfgs import BFGS
    from ase.build import molecule

    system = molecule('CH3CH2OH', vacuum=5.0)
    system.rattle(stdev=0.3)

    # Angles, Bonds, Dihedrals are built up with pairs of constraint
    # value and indices defining the constraint
    # Linear combinations of bond lengths are built up similarly with the
    # coefficients appended to the indices defining the constraint

    # Fix this dihedral angle to whatever it was from the start
    indices = [6, 0, 1, 2]
    dihedral1 = system.get_dihedral(*indices)

    # Fix angle to whatever it was from the start
    indices2 = [6, 0, 1]
    angle1 = system.get_angle(*indices2)

    # Fix bond between atoms 1 and 2 to 1.4
    target_bondlength = 1.4
    indices_bondlength = [1, 2]

    # Fix linear combination of two bond lengths with atom indices 0-8 and
    # 0-6 with weighting coefficients 1.0 and -1.0 to the current value.
    # In other words, fulfil the following constraint:
    # 1 * system.get_distance(0, 8) -1 * system.get_distance(0, 6) = const.
    bondcombo_def = [[0, 8, 1.0], [0, 6, -1.0]]

    def get_bondcombo(system, bondcombo_def):
        return sum([
            defin[2] * system.get_distance(defin[0], defin[1])
            for defin in bondcombo_def
        ])

    target_bondcombo = get_bondcombo(system, bondcombo_def)

    constraint = FixInternals(bonds=[(target_bondlength, indices_bondlength)],
                              angles_deg=[(angle1, indices2)],
                              dihedrals_deg=[(dihedral1, indices)],
                              bondcombos=[(target_bondcombo, bondcombo_def)],
                              epsilon=1e-10)

    print(constraint)

    calc = EMT()

    opt = BFGS(system, trajectory='opt.traj', logfile='opt.log')

    previous_angle = system.get_angle(*indices2)
    previous_dihedral = system.get_dihedral(*indices)
    previous_bondcombo = get_bondcombo(system, bondcombo_def)

    print('angle before', previous_angle)
    print('dihedral before', previous_dihedral)
    print('bond length before', system.get_distance(*indices_bondlength))
    print('(target bondlength %s)', target_bondlength)
    print('linear bondcombination before', previous_bondcombo)

    system.calc = calc
    system.set_constraint(constraint)
    print('-----Optimization-----')
    opt.run(fmax=0.01)

    new_angle = system.get_angle(*indices2)
    new_dihedral = system.get_dihedral(*indices)
    new_bondlength = system.get_distance(*indices_bondlength)
    new_bondcombo = get_bondcombo(system, bondcombo_def)

    print('angle after', new_angle)
    print('dihedral after', new_dihedral)
    print('bondlength after', new_bondlength)
    print('linear bondcombination after', new_bondcombo)

    err1 = new_angle - previous_angle
    err2 = new_dihedral - previous_dihedral
    err3 = new_bondlength - target_bondlength
    err4 = new_bondcombo - previous_bondcombo

    print('error in angle', repr(err1))
    print('error in dihedral', repr(err2))
    print('error in bondlength', repr(err3))
    print('error in bondcombo', repr(err4))

    assert err1 < 1e-11
    assert err2 < 1e-12
    assert err3 < 1e-12
    assert err4 < 1e-12
Exemple #21
0
    def run_calculation(self,
                        coords,
                        label,
                        calc_type="single_point",
                        calculate_force=True,
                        dihedral_freeze=None,
                        ase_constraints=None):
        """
        Method that runs an ASE calculation.

        Parameters
        ----------
        coords : np.ndarray, shape=(n_atoms,3), dtype=float
            Coordinates array.
        label : str or int
            Label of the calculation.
        calc_type : str, default="single_point"
            Available options are "single_point" and "optimization".
        calculate_force : bool
            Whether to calculate forces.
        dihedral_freeze : list of list of int, default=None
            List of lists of wherein each inner list should contain 4 integers defining a torsion to be kept fixed.
        ase_constraints : list of ASE constraints, default=None
            List of ASE constraints to be applied during the scans.
            More information: https://wiki.fysik.dtu.dk/ase/ase/constraints.html

        Returns
        -------
        coord : np.ndarray, shape=(n_atoms,3), dtype=float
             Coordinate array in nanometers.
        energy : float
            Energy value in kJ/mol.
        forces : np.ndarray, shape=(n_atoms,3), dtype=float
            Forces array, kJ/mol/nm.
        """
        from ase.visualize import view

        # Change to calculation directory
        self._interface.chdir(self._calculation_dirs[label], absolute=True)

        # Reset ase calculator
        self._ase_calculator[int(label)].reset()

        # Set calculator in Atoms object
        atoms = ase.Atoms(self._symbols_string, coords)
        atoms.set_calculator(self._ase_calculator[label])

        if not calculate_force:
            forces = None

        if self._cell is not None:
            # Set the cell and center the atoms
            atoms.set_cell(self._cell)
            atoms.center()

        if calc_type.lower() == "single_point":
            # Run calculation and extract potential energy and forces
            # Set calculator in Atoms object
            if calculate_force:
                forces = atoms.get_forces(
                ) * 96.48530749925794 * 10.0  # eV/A to kJ/mol/nm

            energy = atoms.get_potential_energy(
            ) * 96.48530749925794  # eV to kJ/mol

            # View molecule after sp calculation
            if self._view_atoms:
                view(atoms)

            # Go back to main folder
            self._interface.chdir_base()

            return energy, forces
        elif calc_type.lower() == "optimization":
            # Run optimization
            from ase.io import write, read
            logging.info("Performing QM optimization using ASE optimizer.")

            constraints_list = []

            # Apply necessary dihedral constraints
            if dihedral_freeze is not None:
                dihedrals_to_fix = []
                for dihedral in dihedral_freeze:
                    dihedrals_to_fix.append([
                        atoms.get_dihedral(*dihedral) * np.pi / 180.0, dihedral
                    ])

                constraint = FixInternals(bonds=[],
                                          angles=[],
                                          dihedrals=dihedrals_to_fix,
                                          epsilon=self._shake_threshold)
                constraints_list.append(constraint)

            # Apply any ASE constraints
            # More information: https://wiki.fysik.dtu.dk/ase/ase/constraints.html
            if ase_constraints is not None:
                for constraint in ase_constraints:
                    constraints_list.append(constraint)

            if len(constraints_list) > 0:
                atoms.set_constraint(constraints_list)

            opt = self._optimizer(atoms,
                                  trajectory=self._opt_traj_prefix + ".traj",
                                  logfile=self._opt_logfile)
            opt.run(fmax=self._opt_fmax)

            if dihedral_freeze is not None:
                del atoms.constraints

            # View molecule after optimization
            if self._view_atoms:
                view(atoms)

            if calculate_force:
                forces = atoms.get_forces(
                ) * 96.48530749925794 * 10.0  # eV/A to kJ/mol/nm

            # Get data
            coords = atoms.get_positions() * 0.1  # Angstrom to nm
            energy = atoms.get_potential_energy(
            ) * 96.48530749925794  # eV to kJ/mol

            # Go back to main folder
            self._interface.chdir_base()

            return coords, energy, forces
        else:
            raise NotImplementedError(
                "Calculation of type {} is not implemented.".format(calc_type))
Exemple #22
0
def test_qmmm(testdir):
    r = rOH
    a = angleHOH * pi / 180

    # From https://doi.org/10.1063/1.445869
    eexp = 6.50 * units.kcal / units.mol
    dexp = 2.74
    aexp = 27

    D = np.linspace(2.5, 3.5, 30)

    i = LJInteractions({('O', 'O'): (epsilon0, sigma0)})

    # General LJ interaction object
    sigma_mm = np.array([0, 0, sigma0])
    epsilon_mm = np.array([0, 0, epsilon0])
    sigma_qm = np.array([0, 0, sigma0])
    epsilon_qm = np.array([0, 0, epsilon0])
    ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3)

    for calc in [
            TIP3P(),
            SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P()),
            SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P(), vacuum=3.0),
            EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i),
            EIQMMM([3, 4, 5], TIP3P(), TIP3P(), i, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig),
            EIQMMM([3, 4, 5], TIP3P(), TIP3P(), ig, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig, vacuum=3.0)
    ]:
        dimer = Atoms('H2OH2O',
                      [(r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0),
                       (r * cos(a / 2), r * sin(a / 2), 0),
                       (r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0)])
        dimer.calc = calc

        E = []
        F = []
        for d in D:
            dimer.positions[3:, 0] += d - dimer.positions[5, 0]
            E.append(dimer.get_potential_energy())
            F.append(dimer.get_forces())

        F = np.array(F)

        F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D)
        F2 = F[:, :3, 0].sum(1)
        error = abs(F1 - F2).max()
        assert error < 0.01

        dimer.constraints = FixInternals(bonds=[(r, (0, 2)), (r, (1, 2)),
                                                (r, (3, 5)), (r, (4, 5))],
                                         angles_deg=[
                                             (np.degrees(a), (0, 2, 1)),
                                             (np.degrees(a), (3, 5, 4))
                                         ])
        opt = GPMin(dimer,
                    trajectory=calc.name + '.traj',
                    logfile=calc.name + 'd.log')
        opt.run(0.01)

        e0 = dimer.get_potential_energy()
        d0 = dimer.get_distance(2, 5)
        R = dimer.positions
        v1 = R[1] - R[5]
        v2 = R[5] - (R[3] + R[4]) / 2
        a0 = np.arccos(
            np.dot(v1, v2) /
            (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180
        fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}'
        print(fmt.format(calc.name, -min(E), -e0, d0, a0))
        assert abs(e0 + eexp) < 0.002
        assert abs(d0 - dexp) < 0.01
        assert abs(a0 - aexp) < 4

    print(fmt.format('reference', 9.999, eexp, dexp, aexp))
def ase_scan(embedder,
            coords,
            atomnos,
            indexes,
            degrees=10,
            steps=36,
            relaxed=True,
            ad_libitum=False,
            indexes_to_be_moved=None,
            title='temp scan',
            logfile=None):
    '''
    if ad libitum, steps is the minimum number of performed steps
    '''
    assert len(indexes) == 4

    if ad_libitum:
        if not relaxed:
            raise Exception(f'The ad_libitum keyword is only available for relaxed scans.')

    atoms = Atoms(atomnos, positions=coords)
    structures, energies = [], []

    atoms.calc = get_ase_calc(embedder)

    if indexes_to_be_moved is None:
        indexes_to_be_moved = range(len(atomnos))

    mask = np.array([i in indexes_to_be_moved for i, _ in enumerate(atomnos)], dtype=bool)

    t_start = time()

    if logfile is not None:
        logfile.write(f'  > {title}\n')

    for scan_step in range(1000):

        loadbar_title = f'{title} - step {scan_step+1}'
        if ad_libitum:
            print(loadbar_title, end='\r')
        else:
            loadbar_title += '/'+str(steps)
            loadbar(scan_step+1, steps, loadbar_title+' '*(29-len(loadbar_title)))

        if logfile is not None:
            t_start_step = time()

        if relaxed:
            atoms.set_constraint(FixInternals(dihedrals_deg=[[atoms.get_dihedral(*indexes), indexes]]))
            
            with LBFGS(atoms, maxstep=0.2, logfile=None, trajectory=None) as opt:
                
                try:
                    opt.run(fmax=0.05, steps=500)
                    exit_str = 'converged'

                except ValueError: # Shake did not converge
                    exit_str = 'crashed'

                iterations = opt.nsteps


            energies.append(atoms.get_total_energy() * 23.06054194532933) # eV to kcal/mol

        if logfile is not None:
            elapsed = time() - t_start_step
            s = '/' + str(steps) if not ad_libitum else ''
            logfile.write(f'        Step {scan_step+1}{s} - {exit_str} - {iterations} iterations ({time_to_string(elapsed)})\n')

        structures.append(atoms.get_positions())

        atoms.rotate_dihedral(*indexes, angle=degrees, mask=mask)

        if exit_str == 'crashed':
            break

        elif scan_step+1 >= steps:
            if ad_libitum:
                if any((
                    (max(energies) - energies[-1]) > 1,
                    (max(energies) - energies[-1]) > max(energies)-energies[0],
                    (energies[-1] - min(energies)) > 50
                )):

                    # ad_libitum stops when one of these conditions is met:
                    # - we surpassed and are below the maximum of at least 1 kcal/mol
                    # - we surpassed maximum and are below starting point
                    # - current step energy is more than 50 kcal/mol above starting point

                    print(loadbar_title)
                    break
            else:
                break

    structures = np.array(structures)

    clean_directory()

    if logfile is not None:
        elapsed = time() - t_start
        logfile.write(f'{title} - completed ({time_to_string(elapsed)})\n')

    return align_structures(structures, indexes), energies
    if len(f) == 4:
        dih = mol.get_dihedral(f[0] - 1, f[1] - 1, f[2] - 1, f[3] -
                               1)  #ase enumerates atoms starting from zero
        dih *= pi / 180.
        dihedrals.append([dih, [f[0] - 1, f[1] - 1, f[2] - 1, f[3] - 1]])
for c in change:
    if len(c) == 3:
        bonds.append([c[2], [c[0] - 1, c[1] - 1]])
    if len(c) == 4:
        angle = c[3] * pi / 180.
        angles.append([angle, [c[0] - 1, c[1] - 1, c[2] - 1]])
    if len(c) == 5:
        dih = c[4] * pi / 180.
        dihedrals.append([dih, [c[0] - 1, c[1] - 1, c[2] - 1, c[3] - 1]])

cons = FixInternals(bonds=bonds, angles=angles, dihedrals=dihedrals)
mol.set_constraint(cons)

cons.adjust_positions(mol, mol.positions)

try:
    dyn = BFGS(mol, trajectory='%s.traj' % label)
    dyn.run(fmax=0.05)
    db = connect('kinbot.db')
    db.write(mol, name=label, data={{'status': 'normal'}})
except RuntimeError, e:
    print 'error'
    db = connect('kinbot.db')
    db.write(mol, name=label, data={{'status': 'error'}})
"""
try:
def test_dihedralconstraint():
    from math import pi
    from ase.calculators.emt import EMT
    from ase.constraints import FixInternals
    from ase.optimize.bfgs import BFGS
    from ase.build import molecule

    system = molecule('CH3CH2OH', vacuum=5.0)
    system.rattle(stdev=0.3)

    # Angles, Bonds, Dihedrals are built up with  pairs of constraint
    # value and indices defining the constraint

    # Fix this dihedral angle to whatever it was from the start
    indices = [6, 0, 1, 2]
    dihedral1 = system.get_dihedral(*indices)

    # Fix angle to whatever it was from the start
    indices2 = [6, 0, 1]
    angle1 = system.get_angle(*indices2)
    # system.set_dihedral(indices, pi/20, mask=[0,1,1,1,1,1,0,0,0])

    # Fix bond between atoms 1 and 2 to 1.4
    target_bondlength = 1.4
    indices_bondlength = [1, 2]

    constraint = FixInternals(bonds=[(target_bondlength, indices_bondlength)],
                              angles=[(angle1 * pi / 180, indices2)],
                              dihedrals=[(dihedral1 * pi / 180, indices)],
                              epsilon=1e-10)

    print(constraint)

    calc = EMT()

    opt = BFGS(system, trajectory='opt.traj', logfile='opt.log')

    previous_angle = system.get_angle(*indices2)
    previous_dihedral = system.get_dihedral(*indices)

    print('angle before', previous_angle)
    print('dihedral before', previous_dihedral)
    print('bond length before', system.get_distance(*indices_bondlength))
    print('(target bondlength %s)', target_bondlength)

    system.set_calculator(calc)
    system.set_constraint(constraint)
    print('-----Optimization-----')
    opt.run(fmax=0.01)

    new_angle = system.get_angle(*indices2)
    new_dihedral = system.get_dihedral(*indices)
    new_bondlength = system.get_distance(*indices_bondlength)

    print('angle after', new_angle)
    print('dihedral after', new_dihedral)
    print('bondlength after', new_bondlength)

    err1 = new_angle - previous_angle
    err2 = new_dihedral - previous_dihedral
    err3 = new_bondlength - target_bondlength

    print('error in angle', repr(err1))
    print('error in dihedral', repr(err2))
    print('error in bondlength', repr(err3))

    assert err1 < 1e-11
    assert err2 < 1e-12
    assert err3 < 1e-12
Exemple #26
0
    F = []
    for d in D:
        dimer.positions[3:, 0] += d - dimer.positions[5, 0]
        E.append(dimer.get_potential_energy())
        F.append(dimer.get_forces())

    F = np.array(F)

    # plt.plot(D, E)

    F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D)
    F2 = F[:, :3, 0].sum(1)
    error = abs(F1 - F2).max()

    dimer.constraints = FixInternals(
        bonds=[(r, (0, 2)), (r, (1, 2)),
               (r, (3, 5)), (r, (4, 5))],
        angles=[(a, (0, 2, 1)), (a, (3, 5, 4))])
    opt = GPMin(dimer,
               trajectory=calc.name + '.traj', logfile=calc.name + 'd.log')
    opt.run(0.01)

    e0 = dimer.get_potential_energy()
    d0 = dimer.get_distance(2, 5)
    R = dimer.positions
    v1 = R[1] - R[5]
    v2 = R[5] - (R[3] + R[4]) / 2
    a0 = np.arccos(np.dot(v1, v2) /
                   (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180
    fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}'
    print(fmt.format(calc.name, -min(E), -e0, d0, a0))
    assert abs(e0 + eexp) < 0.002
Exemple #27
0
    def run_md(self,
               coords,
               label,
               steps=None,
               dt=None,
               initial_temperature=None,
               integrator=None,
               integrator_args=None,
               dihedral_freeze=None,
               ase_constraints=None):
        """
        Method that runs an ASE calculation.

        Parameters
        ----------
        coords : np.ndarray, shape=(n_atoms,3), dtype=float
            Coordinates array.
        label : str or int
            Label of the calculation.
        steps: int
            Number of steps to take.
        dt : unit.Quantity
            MD Time step.
        initial_temperature : float with ase.unit
            Temperature of MD.
        integrator : ase.md integrator
            ASE integrator.
        integrator_args : dict
            Additional integrator options.
        dihedral_freeze : list of list of int, default=None
            List of lists of wherein each inner list should contain 4 integers defining a torsion to be kept fixed.
        ase_constraints : list of ASE constraints, default=None
            List of ASE constraints to be applied during the scans.
            More information: https://wiki.fysik.dtu.dk/ase/ase/constraints.html

        Returns
        -------
        coord : np.ndarray, shape=(n_atoms,3), dtype=float
             Coordinate array in nanometers.
        energy : float
            Energy value in kJ/mol.
        forces : np.ndarray, shape=(n_atoms,3), dtype=float
            Forces array, kJ/mol/nm.
        """
        from ase.md.velocitydistribution import MaxwellBoltzmannDistribution

        if steps is None:
            assert self._md_steps is not None
            steps = self._md_steps
        if dt is None:
            assert self._md_dt is not None
            dt = self._md_dt
        if initial_temperature is None:
            assert self._md_initial_temperature is not None
            initial_temperature = self._md_initial_temperature
        if integrator is None:
            assert self._md_integrator is not None
            integrator = self._md_integrator
        if integrator_args is None:
            assert self._md_integrator_args is not None
            integrator_args = self._md_integrator_args

        # Change to calculation directory
        self._interface.chdir(self._calculation_dirs[label], absolute=True)

        # Reset ase calculator
        self._ase_calculator[label].reset()

        # Set calculator in Atoms object
        atoms = ase.Atoms(self._symbols_string, coords)
        atoms.set_calculator(self._ase_calculator[label])

        if self._cell is not None:
            # Set the cell and center the atoms
            atoms.set_cell(self._cell)
            atoms.center()

        constraints_list = []

        # Apply necessary dihedral constraints
        if dihedral_freeze is not None:
            dihedrals_to_fix = []
            for dihedral in dihedral_freeze:
                dihedrals_to_fix.append(
                    [atoms.get_dihedral(*dihedral) * np.pi / 180.0, dihedral])

            constraint = FixInternals(bonds=[],
                                      angles=[],
                                      dihedrals=dihedrals_to_fix,
                                      epsilon=self._shake_threshold)
            constraints_list.append(constraint)

        # Apply any ASE constraints
        # More information: https://wiki.fysik.dtu.dk/ase/ase/constraints.html
        if ase_constraints is not None:
            for constraint in ase_constraints:
                constraints_list.append(constraint)

        if len(constraints_list) > 0:
            atoms.set_constraint(constraints_list)

        # Randomize velocities
        MaxwellBoltzmannDistribution(atoms,
                                     initial_temperature,
                                     force_temp=True,
                                     rng=np.random)

        # Get data
        forces_initial = atoms.get_forces(
        ) * 96.48530749925794 * 10.0  # eV/A to kJ/mol/nm
        kinetic_intial = atoms.get_kinetic_energy(
        ) * 96.48530749925794  # eV to kJ/mol
        potential_inital = atoms.get_potential_energy(
        ) * 96.48530749925794  # eV to kJ/mol

        dyn = integrator(
            atoms,
            dt,
            *integrator_args,
            trajectory=self._opt_traj_prefix + ".traj",
            logfile=self._opt_logfile,
        )
        dyn.run(steps)

        # Get data
        forces_final = atoms.get_forces(
        ) * 96.48530749925794 * 10.0  # eV/A to kJ/mol/nm
        coords = atoms.get_positions() * 0.1  # Angstrom to nm
        kinetic_final = atoms.get_kinetic_energy(
        ) * 96.48530749925794  # eV to kJ/mol
        potential_final = atoms.get_potential_energy(
        ) * 96.48530749925794  # eV to kJ/mol

        # View molecule after sp calculation

        self._interface.chdir_base()

        return coords, potential_inital, kinetic_intial, forces_initial, potential_final, kinetic_final, forces_final
Exemple #28
0
#NOTE: you will need to set a sensible calculator for this to give results!
molecule.set_calculator(EMT())

deloc = Delocalizer(molecule)

assert 0

#constraining all stretches with FixInternals
stretch_ind = deloc.ic.getStretchBendTorsOop()[0][0]
stretches = deloc.ic.getStretchBendTorsOop()[1]
bonds = []
for i in range(len(stretch_ind)):
    i, j = stretches[i] - 1
    print i, j
    bonds.append([molecule.get_distance(i, j), [i, j]])

f = FixInternals(bonds=bonds, angles=[], dihedrals=[])
#molecule.set_constraint(f)

bh = BetterHopping(atoms=molecule,
                   temperature=100 * kB,
                   dr=1.0,
                   optimizer=BFGS,
                   fmax=0.025,
                   logfile='tt.log',
                   maxmoves=50,
                   movemode=1,
                   numdelocmodes=20,
                   constrain=True)
bh.run(50)
Exemple #29
0
def test_qmmm_tip4p():
    from math import cos, sin, pi

    import numpy as np
    #import matplotlib.pyplot as plt

    import ase.units as units
    from ase import Atoms
    from ase.calculators.tip4p import TIP4P, epsilon0, sigma0, rOH, angleHOH
    from ase.calculators.qmmm import (SimpleQMMM, EIQMMM, LJInteractions,
                                      LJInteractionsGeneral)
    from ase.constraints import FixInternals
    from ase.optimize import BFGS

    r = rOH
    a = angleHOH * pi / 180

    # From https://doi.org/10.1063/1.445869
    eexp = 6.24 * units.kcal / units.mol
    dexp = 2.75
    aexp = 46

    D = np.linspace(2.5, 3.5, 30)

    i = LJInteractions({('O', 'O'): (epsilon0, sigma0)})

    # General LJ interaction object
    sigma_mm = np.array([sigma0, 0, 0])
    epsilon_mm = np.array([epsilon0, 0, 0])
    sigma_qm = np.array([sigma0, 0, 0])
    epsilon_qm = np.array([epsilon0, 0, 0])
    ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3)

    for calc in [
            TIP4P(),
            SimpleQMMM([0, 1, 2], TIP4P(), TIP4P(), TIP4P()),
            SimpleQMMM([0, 1, 2], TIP4P(), TIP4P(), TIP4P(), vacuum=3.0),
            EIQMMM([0, 1, 2], TIP4P(), TIP4P(), i),
            EIQMMM([3, 4, 5], TIP4P(), TIP4P(), i, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP4P(), TIP4P(), i, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP4P(), TIP4P(), ig),
            EIQMMM([3, 4, 5], TIP4P(), TIP4P(), ig, vacuum=3.0),
            EIQMMM([0, 1, 2], TIP4P(), TIP4P(), ig, vacuum=3.0)
    ]:
        dimer = Atoms('OH2OH2', [(0, 0, 0), (r * cos(a), 0, r * sin(a)),
                                 (r, 0, 0), (0, 0, 0),
                                 (r * cos(a / 2), r * sin(a / 2), 0),
                                 (r * cos(a / 2), -r * sin(a / 2), 0)])
        dimer.calc = calc

        E = []
        F = []
        for d in D:
            dimer.positions[3:, 0] += d - dimer.positions[3, 0]
            E.append(dimer.get_potential_energy())
            F.append(dimer.get_forces())

        F = np.array(F)

        #plt.plot(D, E)

        F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D)
        F2 = F[:, :3, 0].sum(1)
        error = abs(F1 - F2).max()
        assert error < 0.01

        dimer.constraints = FixInternals(bonds=[(r, (0, 1)), (r, (0, 2)),
                                                (r, (3, 4)), (r, (3, 5))],
                                         angles=[(a, (2, 0, 1)),
                                                 (a, (5, 3, 4))])
        opt = BFGS(dimer,
                   maxstep=0.04,
                   trajectory=calc.name + '.traj',
                   logfile=calc.name + 'd.log')
        opt.run(0.01)

        e0 = dimer.get_potential_energy()
        d0 = dimer.get_distance(0, 3)
        R = dimer.positions
        v1 = R[2] - R[3]
        v2 = R[3] - (R[5] + R[4]) / 2
        a0 = np.arccos(
            np.dot(v1, v2) /
            (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180
        fmt = '{0:>23}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}'
        print(fmt.format(calc.name, -min(E), -e0, d0, a0))
        assert abs(e0 + eexp) < 0.002
        assert abs(d0 - dexp) < 0.006
        assert abs(a0 - aexp) < 2.5

    print(fmt.format('reference', 9.999, eexp, dexp, aexp))
Exemple #30
0
if 'CONSATOM3' in i and 'CONTINUE_3PT' in i:
    from Classes_ASE import LockedTo3AtomPlane
    print('3 Atom Constraint cont.')
    a = read('POSCAR')# type: Atoms
    c = LockedTo3AtomPlane(i['DIFFATOM'], (i['CONSATOM1'], i['CONSATOM2'], i['CONSATOM3']), a.positions[i['DIFFATOM']])
elif 'CONSTYPE' in i and i['CONSTYPE'] == 'Bond':
    if 'ITERATE' in i and i['ITERATE']:
        from ase.constraints import FixInternals
        print('Constraining Bonds to fixed length')
        bond1 = atoms.get_distance(i['DIFFATOM'], i['CONSATOM1'], mic=True)
        bond2 = atoms.get_distance(i['DIFFATOM'], i['CONSATOM2'], mic=True)
        bonds = [
            [ bond1, [ i['DIFFATOM'], i['CONSATOM1'] ] ],
            [ bond2, [ i['DIFFATOM'], i['CONSATOM2'] ] ]
                ]
        c = FixInternals(bonds=bonds)
        def iterate(atoms : Atoms):
            delta = 0.01
            global bond1
            global bond2
            force = atoms.get_forces()[i['DIFFATOM']]
            bond1_dist   = atoms.get_distance(i['DIFFATOM'], i['CONSATOM1'], vector=False)
            bond1_vector = atoms.get_distance(i['DIFFATOM'], i['CONSATOM1'], vector=True )
            bond1_unit = bond1_vector / bond1_dist
            bond2_dist   = atoms.get_distance(i['DIFFATOM'], i['CONSATOM2'], vector=False)
            bond2_vector = atoms.get_distance(i['DIFFATOM'], i['CONSATOM2'], vector=True )
            bond2_unit = bond2_vector / bond2_dist

            bond1_projection = np.dot(force, bond1_unit)
            bond2_projection = np.dot(force, bond2_unit)
            if abs(bond1_projection) > bond2_projection: