예제 #1
0
def generate_frames():
    '''
    This function generates the NEB pathway we want to study.

    **Returns**

        frames: *list, list,* :class:`structures.Atom`
            MEP reaction coordinate.
    '''
    PROXIMITY = 3.0
    DELTA = 0.5
    NFRAMES = 10

    minimize_benzene()

    mol1 = files.read_cml("benzene_opt.cml", return_molecules=True)[0]
    mol2 = files.read_cml("benzene_opt.cml", return_molecules=True)[0]
    mol1.set_center((0.0, 0.0, 0.0))
    mol1.rotate(geometry.rotation_matrix((0, 0, 1), 30))
    mol2.set_center((0.0, 0.0, PROXIMITY))

    frames = []
    for i in range(NFRAMES):
        mol2.set_center((0.0, 0.0, PROXIMITY + i * DELTA))
        frames.append(copy.deepcopy(mol1.atoms + mol2.atoms))

    return frames
예제 #2
0
def minimize_benzene():
    '''
    This function will use LAMMPs minimize to ensure that our endpoints
    are minimized.
    '''

    P, mol1 = files.read_cml("benzene.cml", new_method=True)
    box = structures.System(name="benz", box_size=(20, 20, 20), periodic=True)
    mol1 = mol1[0]
    box.add(mol1)
    box.set_types(P)

    input_script = """units real
atom_style full
pair_style lj/cut/coul/cut 10.0
bond_style harmonic
angle_style harmonic
dihedral_style opls

boundary p p p
read_data benz.data

pair_modify mix geometric

""" + box.dump_pair_coeffs() + """

dump 1 all xyz 1 benzene.xyz
dump_modify 1 element """ + ' '.join(box.get_elements(P)) + """

minimize 1.0e-4 1.0e-6 1000 10000
"""
    input_script = input_script.strip()
    j = lammps_job.job("benz",
                       input_script,
                       system=box,
                       procs=1,
                       queue=None,
                       hybrid_angle=False,
                       params=P,
                       pair_coeffs_included=False,
                       no_echo=True)
    j.wait(1)

    new_atoms = files.read_xyz("lammps/benz/benzene.xyz")[-1]
    for a, b in zip(mol1.atoms, new_atoms):
        a.x, a.y, a.z = b.x, b.y, b.z

    files.write_cml(mol1, name="benzene_opt")
예제 #3
0
def test_read_cml():

    # atoms, bonds, angles, dihedrals = files.read_cml("misc/acetone.cml", new_method=False)

    P, molecs = files.read_cml("misc/acetone.cml", new_method=True)
    P.set_opls_mask()
    # print P.dump_style("opls")

    # print P.dihedral_params
    # print P.dihedral_params.index(('4', '3', '3', '13'))

    # print molecs[0].bonds[0].type

    test_sys = structures.System()
    test_sys.add(molecs[0])

    files.write_lammps_data(test_sys, new_method=True, params=P)

    return False
예제 #4
0
from squid import files
from squid import lammps
from squid import geometry
from squid import structures

if __name__ == "__main__":
    # Step 1 - Generate the system
    world = structures.System("solv_box",
                              box_size=(15.0, 15.0, 15.0),
                              periodic=True)

    # Step 2 - Get any molecules you want
    mol1 = files.read_cml("benzene.cml")[0]
    mol2 = mol1 + (10, 10, 10)
    solv = files.read_cml("acetone.cml")[0]

    # Step 3 - In the case that we do not know the atom types, but we still
    # want to generate a lammps data file, we can still do so!  We must first
    # in this example strip away all relevant bonding information.  Further,
    # and this is important: YOU MUST SET a.label and a.charge to the element
    # and some value (in this example I set it to 0.0).
    for mol in [mol1, mol2, solv]:
        for a in mol.atoms:
            a.label = a.element
            a.charge = 0.0
        mol.bonds = []
        mol.angles = []
        mol.dihedrals = []

    # Step 4 - Add them however you want
    world.add(mol1)
예제 #5
0
def run_simulation(NEB, i, state, charge, multiplicity, procs, queue,
                   initial_guess, extra_section, mem, priority):
    '''
    This function will, given the coordinates from NEB, run a LAMMPs
    simulation with a solvated system.

    **Parameters**

        NEB: :class:`NEB`
            An NEB container holding the main NEB simulation
        i: *int*
            The index corresponding to which image on the frame is to be
            simulated.
        state: *list,* :class:`structures.Atom`
            A list of atoms describing the image on the frame associated
            with index *i*.
        charge: *int*
            Charge of the system.
        multiplicity: *int*
            Multiplicity of the system.
        procs: *int*
            The number of processors to use during calculations.
        queue: *str*
            Which queue to submit the simulation to (this is queueing system
            dependent).
        initial_guess: *str*
            The name of a previous simulation for which we can read in a
            hessian.
        extra_section: *str*
            Extra settings for this DFT method.
        mem: *int*
            How many Mega Words (MW) you wish to have as dynamic memory.
        priority: *int*
            Whether to submit the job with a given priority (NBS). Not setup for
            this function yet.

    **Returns**

        lmp_job: :class:`jobs.Job`
            A job container holding the simulation.
    '''

    theory, density = NEB.theory
    step = NEB.step

    if not theory.endswith(".cml"):
        theory += ".cml"
    if not os.path.exists(theory):
        raise Exception(
            "Cannot find desired solvent molecule in the folder (%s)." %
            theory)

    P1, solv = files.read_cml(theory, new_method=True)
    P2, benz1 = files.read_cml("benzene.cml", new_method=True)
    _, benz2 = files.read_cml("benzene.cml", new_method=True)
    solv, benz1, benz2 = solv[0], benz1[0], benz2[0]

    P = P1 + P2
    solv.set_types(P)
    benz1.set_types(P)
    benz2.set_types(P)

    # First, pack into benz1 and benz2 the coodinates
    new_benz_1 = np.array([s.flatten() for s in state[:len(state) / 2]])
    new_benz_2 = np.array([s.flatten() for s in state[len(state) / 2:]])
    benz1.set_positions(new_benz_1)
    benz2.set_positions(new_benz_2)

    # Generate our system
    BOX_SIZE = (10.0, 10.0, 15.0)
    box = structures.System("solv_box-%d-%d" % (step, i),
                            box_size=BOX_SIZE,
                            periodic=True)
    box.add(benz1)
    box.add(benz2)

    box.packmol([solv], density=density, new_method=True, tolerance=1.0)
    box.set_types(P)

    # Run the simulation
    input_script = """units real
atom_style full
pair_style lj/cut/coul/cut 10.0
bond_style harmonic
angle_style harmonic
dihedral_style opls

boundary p p p
read_data solv_box-""" + str(step) + """-""" + str(i) + """.data

pair_modify mix geometric

""" + box.dump_pair_coeffs() + """

group neb id <= """ + str(len(state)) + """
group solvent subtract all neb

#dump 1 all xyz 1000 solv_box_""" + str(i) + """.xyz
#dump_modify 1 element """ + ' '.join(box.get_elements(P)) + """
#dump 2 neb xyz 100 neb.xyz

thermo_style custom ke pe temp press
thermo 1000

velocity neb zero linear
fix freeze neb setforce 0.0 0.0 0.0

minimize 1.0e-4 1.0e-6 1000 10000

velocity all create 300.0 23123 rot yes dist gaussian
velocity neb set 0.0 0.0 0.0
timestep 1.0

fix energy neb ave/time 100 5 1000 c_thermo_pe file energy.profile
fix motion_npt all npt temp 300.0 300.0 100.0 iso 0.0 0.0 1000.0 dilate solvent
run 1000000
unfix motion_npt

compute pe neb pe/atom
dump forces neb custom 1 forces.dump id element x y z fx fy fz c_pe
dump glance all xyz 1 solv_box_""" + str(i) + """.xyz
dump_modify glance element """ + ' '.join(box.get_elements(P)) + """
unfix freeze
run 0
"""

    return lammps_job.job("solv_box-%d-%d" % (step, i),
                          input_script,
                          system=box,
                          procs=procs,
                          queue=queue,
                          params=P,
                          pair_coeffs_included=False,
                          no_echo=True)
예제 #6
0
def generate_ion_halide_cation(halide,
                               cation,
                               fname,
                               route,
                               extra_section,
                               ion="Pb",
                               run_opt=True,
                               priority=None,
                               walltime="3-0:0:0",
                               procs=2):
    """
    Check if a perovskite monomer system already exists. If so, then read in
    the CML and return it. If not, then generate the system, save it, and
    return the generated system.

    **Parameters**

        halide: *list, str or str*
            The halide combination in the perovskite. If a string is passed,
            all three are assumed to be the same
        cation: *str*
            The cation in the perovskite.
        ion: *str, optional*
            The ion to use within this perovskite.
        run_opt: *bool, optional*
            Whether to geometry optimize the system if it did not exist.
        priority: *int, optional*
            A queue priority to ensure the subjobs run.  This may be necessary if
            many simulations are run in parallel and you are worried about locking
            the queue with too many parent jobs.

    **Returns**

        system: *Molecule*
            A molecule object holding the perovskite monomer system.
    """

    if os.path.exists(WORLD_CONSTS.STRUCTURES_PATH + fname + ".cml"):
        system = structures.Molecule(
            files.read_cml(WORLD_CONSTS.STRUCTURES_PATH + fname + ".cml",
                           test_charges=False,
                           default_angles=WORLD_CONSTS.default_angles,
                           allow_errors=True)[0])
        return system

    def vdw(y):
        return constants.PERIODIC_TABLE[units.elem_s2i(y)]['vdw_r']

    # Get the ionX3 system
    ionX3 = _generate_ion_halide(halide, ion=ion)

    # Get the cation from the cml file
    atoms, bonds, _, _ = files.read_cml(
        WORLD_CONSTS.STRUCTURES_PATH + cation + ".cml",
        test_charges=False,
        default_angles=WORLD_CONSTS.default_angles,
        allow_errors=True)

    system = structures.Molecule(atoms)

    # Align along X axis
    system.atoms = geometry.align_centroid(system.atoms)[0]
    # Rotate to Z axis
    # NOTE! In case of FA, we want flat so only translate to origin instead
    elems = [a.element for a in system.atoms]
    if cation == "FA":
        system.translate(system.get_center_of_mass())
    else:
        R = geometry.rotation_matrix([0, 1, 0], 90, units="deg")
        system.rotate(R)
    # If N and C in system, ensure N is below C (closer to Pb)
    if "N" in elems and "C" in elems:
        N_index = [i for i, a in enumerate(system.atoms)
                   if a.element == "N"][0]
        C_index = [i for i, a in enumerate(system.atoms)
                   if a.element == "C"][0]
        if system.atoms[N_index].z > system.atoms[C_index].z:
            # Flip if needed
            R = geometry.rotation_matrix([0, 1, 0], 180, units="deg")
            system.rotate(R)

    # Offset system so lowest point is at 0 in the z dir
    z_offset = min([a.z for a in system.atoms]) * -1
    system.translate([0, 0, z_offset])

    # Add to the ionX3 system with an offset of vdw(Pb)
    system.translate([0, 0, vdw(ion)])
    system.atoms += ionX3.atoms

    # Run a geometry optimization of this system
    if run_opt:
        ionXY = orca.job(fname,
                         route,
                         atoms=system.atoms,
                         extra_section=extra_section,
                         redundancy=True,
                         queue=sysconst.default_queue,
                         priority=priority,
                         walltime=walltime,
                         procs=procs)
        time.sleep(SLEEPER)
        ionXY.wait()
        time.sleep(SLEEPER)
        results = orca.read(fname)
        new_pos = results.atoms
        for a, b in zip(system.atoms, new_pos):
            a.x, a.y, a.z = [b.x, b.y, b.z]

        if not hasattr(ionXY, "redundancy"):
            dump_log(results, fname)

    # Set OPLS types
    for i, a in enumerate(system.atoms):
        a.index = i + 1
        if a.element in WORLD_CONSTS.atom_types and a.type is None:
            a.type = structures.Struct()
            a.type.__dict__.update(WORLD_CONSTS.atom_types[a.element])
            a.type_index = a.type.index

    # Write cml file so we don't re-generate, and return system
    files.write_cml(system,
                    bonds=bonds,
                    name=WORLD_CONSTS.STRUCTURES_PATH + fname + ".cml")
    return system
예제 #7
0
from squid.ff_params import Parameters

# Generate the system object to hold our solvent
solvent_box = structures.System(name="solv_box",
                                box_size=(15.0, 15.0, 15.0),
                                box_angles=(90.0, 90.0, 90.0),
                                periodic=True)

########## OPTION 1
# Read in our molecule, with minimal parameter object, and assign types
# P, acetone = files.read_cml("acetone.cml", new_method=True)
# acetone = acetone[0]

########## OPTION 2
# Read in cml files normally
acetone = files.read_cml("acetone.cml", return_molecules=True)
acetone = acetone[0]

# Get a parameter object, and assign to molecule
P = Parameters(restrict=[a.label for a in acetone.atoms])
acetone.set_types(P)
###################

# Using packmol, pack this box with acetic acids
solvent_box.packmol([acetone], new_method=True, density=0.791, seed=21321)

# Assign the types
solvent_box.set_types(P)

# Now we can run an NPT simulation using lammps
# Get a list of elements for dump_modify.  By default we organize types by heaviest to lightest, so do so here.