def wrongbox(self):
     box = mbuild.Compound()
     box.box = mbuild.Box([5.0, 5.0, 5.0])
     return box
Exemple #2
0
 def test_init_with_subcompounds1(self, ethane):
     compound = mb.Compound(ethane)
     assert compound.n_particles == 8
     assert compound.n_bonds == 7
Exemple #3
0
 def test_init_with_subcompounds3(self, ethane, h2o):
     compound = mb.Compound([ethane, [h2o, mb.clone(h2o)]])
     assert compound.n_particles == 8 + 2 * 3
     assert compound.n_bonds == 7 + 2 * 2
Exemple #4
0
 def test_clone_outside_containment(self, ch2, ch3):
     compound = mb.Compound()
     compound.add(ch2)
     mb.force_overlap(ch3, ch3['up'], ch2['up'])
     with pytest.raises(MBuildError):
         ch3_clone = mb.clone(ch3)
Exemple #5
0
    def __init__(self,
                 lipids,
                 ref_atoms,
                 n_lipids_x=10,
                 n_lipids_y=10,
                 area_per_lipid=1.0,
                 solvent=None,
                 lipid_box=None,
                 spacing_z=0.5,
                 solvent_per_lipid=None,
                 n_solvent=None,
                 random_seed=12345,
                 mirror=True):
        super(Bilayer, self).__init__()

        # Santitize inputs.
        if sum([lipid[1] for lipid in lipids]) != 1.0:
            raise ValueError('Lipid fractions do not add up to 1.')
        assert len(ref_atoms) == len(lipids)

        self.lipids = lipids
        self.ref_atoms = ref_atoms
        self._lipid_box = lipid_box

        # 2D Lipid locations.
        self.n_lipids_x = n_lipids_x
        self.n_lipids_y = n_lipids_y
        self.apl = area_per_lipid
        self.n_lipids_per_layer = self.n_lipids_x * self.n_lipids_y
        self.pattern = mb.Grid2DPattern(n_lipids_x, n_lipids_y)
        self.pattern.scale(np.sqrt(self.apl * self.n_lipids_per_layer))

        # Solvent info.
        self.solvent = solvent
        self.n_solvent = n_solvent
        self.solvent_per_lipid = solvent_per_lipid

        # Other inputs.
        self.spacing = np.array([0, 0, spacing_z])
        self.random_seed = random_seed
        self.mirror = mirror

        self._number_of_each_lipid_per_layer = []
        self._solvent_per_layer = None

        # Containers for lipids and solvent.
        self.lipid_components = mb.Compound()
        self.solvent_components = mb.Compound()

        # Assemble the lipid layers
        seed(self.random_seed)
        top_layer, top_lipid_labels = self.create_layer()
        self.lipid_components.add(top_layer)
        if self.mirror == True:
            bottom_layer, bottom_lipid_labels = self.create_layer(
                lipid_indices=top_lipid_labels, flip_orientation=True)
        else:
            bottom_layer, bottom_lipid_labels = self.create_layer(
                flip_orientation=True)
        self.lipid_components.add(bottom_layer)

        # solvate the lipids
        #self.solvate_bilayer()  # TODO: needs fixing

        # add everything to the big list
        self.add(self.lipid_components)
        self.add(self.solvent_components)
        print(self.number_of_each_lipid_per_layer)
Exemple #6
0
 def test_batch_add(self, ethane, h2o):
     compound = mb.Compound()
     compound.add([ethane, h2o])
     assert compound.n_particles == 8 + 3
     assert compound.n_bonds == 7 + 2
Exemple #7
0
 def test_parmed_box(self, h2o):
     compound = mb.Compound()
     compound.add(h2o)
     tilted_box = mb.Box(lengths=[2.0, 2.0, 2.0], angles=[60.0, 80.0, 100.0])
     structure = compound.to_parmed(box=tilted_box)
     assert all(structure.box == [20.0, 20.0, 20.0, 60.0, 80.0, 100.0])
Exemple #8
0
def main():
    # Create a CG methane, load and apply ff
    methane = mbuild.Compound(name="_CH4")
    ff_path = resource_filename(
        "mc_examples",
        "realistic_workflows/zeolite_adsorption/resources/ffxml/adsorbates.xml",
    )
    ff_ads = foyer.Forcefield(ff_path)
    methane_ff = ff_ads.apply(methane)

    # Define a few keyword args that will be the
    # same for all fluid phase simulations
    custom_args = {
        "charge_style": "none",
        "vdw_cutoff": 14.0 * u.angstrom,
        "prop_freq": 10,
    }

    # Define temperatures and chemical potential values
    # for the single phase GCMC simulations
    temperatures = [298 * u.K, 309 * u.K, 350 * u.K]
    mus = np.arange(-49, -30, 3) * u.Unit("kJ/mol")

    # Loop over temperatures and mus and run simulations
    for temperature in temperatures:
        for mu in mus:

            # For each simulation -- first estimate
            # the box volume to target ~40 molecules
            n_methane_target = 40
            beta = 1.0 / (u.kb * temperature)
            mass = 16.04 * u.amu
            debroglie = np.sqrt(2 * np.pi * u.hbar**2 * beta / mass)
            vol = n_methane_target * debroglie**3 * np.exp(
                -beta.to("mol/kJ") * mu)
            boxl = (vol**(1.0 / 3.0)).to_value("nm")
            if boxl < 2.0 * custom_args["vdw_cutoff"].to_value("nm"):
                boxl = 2.0 * custom_args["vdw_cutoff"].to_value("nm")

            # Define the species list, box list, system, moveset
            # We start with an empty box
            species_list = [methane_ff]
            box_list = [mbuild.Box([boxl, boxl, boxl])]
            system = mc.System(box_list, species_list)
            moveset = mc.MoveSet("gcmc", species_list)

            # Create a new directory, temporary cd, and run
            # the equilibration and production simulations!
            print(f"\nRun simulation: T = {temperature}, mu = {mu}\n")
            dirname = f"fluid_T_{temperature:0.1f}_mu_{mu:.1f}".replace(
                " ", "_").replace("/", "-")
            if not os.path.isdir(dirname):
                os.mkdir(dirname)
            else:
                pass
            with temporary_cd(dirname):
                mc.run(
                    system=system,
                    moveset=moveset,
                    run_type="equil",
                    run_length=50000,
                    temperature=temperature,
                    run_name="equil",
                    chemical_potentials=[mu],
                    **custom_args,
                )

                mc.restart(
                    restart_from="equil",
                    run_name="prod",
                    run_type="prod",
                    total_run_length=400000,
                )
    def __init__(self,
                 radius=2,
                 angle=90.0,
                 fluid=None,
                 density=None,
                 lattice=None,
                 lattice_compound=None,
                 x=None,
                 y=None):

        super(Droplet, self).__init__()

        if fluid is None:
            raise ValueError('Fluid droplet compounds must be specified')
        if density is None:
            raise ValueError('Fluid density must be specified (units kg/m^3)')

        if x:
            if x < radius * 4:
                raise ValueError(
                    'Dimension x of sheet must be at least radius * 4')
            elif x > 100:
                raise ValueError(
                    'Dimension x of sheet must be less than 100 nm')
        else:
            x = radius * 4

        if y:
            if y < radius * 4:
                raise ValueError(
                    'Dimension y of sheet must be at least radius * 4')
            elif y > 100:
                raise ValueError(
                    'Dimension y of sheet must be less than 100 nm')
        else:
            y = radius * 4

        # Default to graphene lattice
        if lattice is None:

            if lattice_compound is not None:
                raise ValueError(
                    'If Lattice is None, defaults to a Graphene surface. ' +
                    'In this case, do not specify lattice_compound.')

            lattice_compound = mbuild.Compound(name='C')
            lattice_spacing = [0.2456, 0.2456, 0.335]
            angles = [90.0, 90.0, 120.0]
            carbon_locations = [[0, 0, 0], [2 / 3, 1 / 3, 0]]
            basis = {lattice_compound.name: carbon_locations}
            lattice = mbuild.Lattice(lattice_spacing=lattice_spacing,
                                     angles=angles,
                                     lattice_points=basis)
            compound_dict = {lattice_compound.name: lattice_compound}

            factor = np.cos(np.pi / 6)  # fixes non-cubic lattice
            # Estimate the number of lattice repeat units
            replicate = [int(x / 0.2456), int(y / 0.2456) * (1 / factor)]

            lat = lattice.populate(compound_dict=compound_dict,
                                   x=replicate[0],
                                   y=replicate[1],
                                   z=3)

            for particle in lat.particles():
                if particle.xyz[0][0] < 0:
                    particle.xyz[0][0] += lat.periodicity[0]
            lat.periodicity[1] *= factor

        else:
            if lattice_compound is None:
                raise ValueError('Lattice compounds must be specified')

            if not np.all(lattice.angles == 90.0):
                raise ValueError(
                    'Currently, only cubic lattices are supported. ' +
                    'If using Graphene, do not pass in a Lattice.')

            compound_dict = {lattice_compound.name: lattice_compound}
            lat = lattice.populate(compound_dict=compound_dict,
                                   x=int(x / lattice.lattice_spacing[0]),
                                   y=int(y / lattice.lattice_spacing[1]),
                                   z=int(1.5 / lattice.lattice_spacing[2]))

        sheet = mbuild.clone(lat)
        self.surface_height = np.max(sheet.xyz, axis=0)[2]
        coords = list(sheet.periodicity)

        height = get_height(radius, angle)
        sphere_coords = [coords[0] / 2, coords[1] / 2, radius, radius]
        sphere = mbuild.fill_sphere(compound=fluid,
                                    sphere=sphere_coords,
                                    density=density)

        to_remove = []
        for child in sphere.children:
            for atom_coords in child.xyz:
                if height > radius:
                    if atom_coords[2] < height - radius:
                        to_remove += child
                        break
                else:
                    if atom_coords[2] < height:
                        to_remove += child
                        break

        sphere.remove(to_remove)

        sheet.name = 'LAT'
        sphere.name = 'FLD'
        sphere.xyz -= [0, 0, np.min(sphere.xyz, axis=0)[2]]
        sphere.xyz += [0, 0, self.surface_height + 0.3]

        self.add(sheet)
        self.add(sphere)
        self.periodicity[0] = sheet.periodicity[0]
        self.periodicity[1] = sheet.periodicity[1]
        self.periodicity[2] = radius * 5
from dropletbuilder.dropletbuilder import GrapheneDroplet
import mbuild
from mbuild.examples.alkane.alkane import Alkane
from dropletbuilder.utils.io_tools import get_fn
from foyer import Forcefield

# build the lattice
lattice_compound = mbuild.Compound(name='Au')
lattice_spacing = [0.40788, 0.40788, 0.40788]
lattice_vector = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
gold_locations = [[0., 0., 0.], [.5, .5, 0.], [.5, 0., .5], [0, .5, .5]]
basis = {lattice_compound.name: gold_locations}
gold_lattice = mbuild.Lattice(lattice_spacing=lattice_spacing,
                              lattice_vectors=lattice_vector,
                              lattice_points=basis)

# hexane compound
hexane = Alkane(n=6)
hexane.name = 'HEX'

# build the system
system = GrapheneDroplet(radius=3,
                         angle=90,
                         fluid=hexane,
                         density=655,
                         lattice=gold_lattice,
                         lattice_compound=lattice_compound)

# get and apply forcefields
AU = Forcefield(get_fn('heinz2008.xml'))
OPLSAA = Forcefield(name='oplsaa')
Exemple #11
0
index = 0
# Loop through each type of molecule (DSPC, DPPC, etc.)
for i, lipid_type in enumerate(lipid_system_info):
    # Loop through the quantity of that particular molecule
    for n in range(int(lipid_type[1])):
        lipid_molecule = lipid_type[0]
        lipid_offset = lipid_type[2]
        top_lipids.append([lipid_molecule, lipid_offset])
        bot_lipids.append([lipid_molecule, lipid_offset])
        index += 1

if len(bot_lipids) != n_lipid:
    sys.exit('Error setting up system components')

# Generate bottom layer randomly
bot_layer = mb.Compound()
for i in range(n_x):
    for j in range(n_y):
        # Randomly select a lipid that has not yet been selected
        random_lipid = np.random.randint(0, len(bot_lipids))
        # Create the mbuild Molecule for this lipid
        molecule_i = bot_lipids.pop(random_lipid)
        molecule_to_add = mb.clone(molecule_i[0])
        # Apply tilt angle
        mb.spin_y(molecule_to_add, tilt_angle)
        # Apply z_offset
        z_offset = molecule_i[1]
        #z_offset = 0
        # Apply APL and z_offset to identify the position for the molecule in the grid
        position = [i * spacing, j * spacing, z_offset]
        mb.translate(molecule_to_add, position)
Exemple #12
0
def make_leaflet(leaflet_info,
                 n_x=8,
                 n_y=8,
                 tilt_angle=0,
                 spacing=0,
                 random_z_displacement=0):
    """ Generate a leaflet by laying down molecules in a 2D grid at random grid points

    Parameters
    ---------
    n_x : int
        Number of lipids in x direction
    n_y : int
        Number of lipids in y direction
    leaflet_info : n x 3 array
        Each row corresponds to a molecule
        First column is the mB.compound
        Second column is the number of that molecule
        Third column is a z-offset specific to molecules of that type (positive means closer to the solvent,
            negative means deeper inside the bilayer)
    tilt_angle : float (rad)
        tilt angle (spun around y-axis)
    spacing : float (nm)
        spacing between leaflets, based on area per lipid
    random_z_displacement : float (nm)
        Randomly offset molecules by a small amount
       
    Returns
    -------
    leaflet : mb.Compound()
        Leaflet of molecules
      
    """

    _validate_leaflet_info(leaflet_info, n_x, n_y)

    leaflet = mb.Compound()

    # Create ordered pairs
    ordered_pairs = []
    for i, j in product(range(n_x), range(n_y)):
        ordered_pairs.append((i, j))

    # Randomly assign ordered pairs to each lipid
    # based on the way lipids is set, all of one molecule is listed first
    # before getting to the next one
    # Loop through each type of molecule (DSPC, DPPC, etc.)
    for i, lipid_type in enumerate(leaflet_info):
        # Loop through the system's quantity of that particular molecule
        for n in range(lipid_type[1]):
            random_index = np.random.randint(0, len(ordered_pairs))
            (i, j) = ordered_pairs.pop(random_index)

            # Do geometry transformations
            molecule_to_add = mb.clone(lipid_type[0])
            # Apply tilt angle
            molecule_to_add.spin(tilt_angle, [0, 1, 0])

            # Apply z_offset
            z_offset = lipid_type[2]

            # Apply APL and z_offset to identify the position for the
            # molecule in the grid
            position = [
                i * spacing, j * spacing,
                z_offset + (-1 * np.random.random() * random_z_displacement)
            ]
            molecule_to_add.translate(position)

            # Add the new molecule to the leaflet
            leaflet.add(molecule_to_add)

    return leaflet
Exemple #13
0
        self.add_bond([n, c5])
        self.add_bond([c5, c6])

        self.add(mb.Port(anchor=c5), 'up')
        self.add(mb.Port(anchor=c6), 'down')


# Implicit hydrogens
# XYZ doesn't matter, we just need bonds and particle names
# So we can upload to charmm-gui
cap_with = 'H'
pvp = mb.Polymer(mvp(), n=2)

if cap_with == 'C':
    c_top = mb.Particle(name='C')
    cap_top = mb.Compound()
    cap_top.add(c_top)
    cap_top.add(mb.Port(anchor=c_top), 'down')
    mb.force_overlap(cap_top, cap_top['down'], pvp['up'])

    c_bot = mb.Particle(name='C')
    cap_bot = mb.Compound()
    cap_bot.add(c_bot)
    cap_bot.add(mb.Port(anchor=c_bot), 'up')
    mb.force_overlap(cap_bot, cap_bot['up'], pvp['down'])
    pvp.add(cap_top)
    pvp.add(cap_bot)

elif cap_with == 'H':
    pass
Exemple #14
0
import mbuild
import foyer
import unyt as u
import mosdef_cassandra as mc

# Load the force field from foyer
ff = foyer.forcefields.load_TRAPPE_UA()

# Create a single site methane molecule
methane = mbuild.Compound(name="_CH4")

# Apply the force field
methane_ff = ff.apply(methane)

# Create an empty 3x3x3 nm^3 simulation box
box = mbuild.Box([3., 3., 3.])

# Define the box/species lists
box_list = [box]
species_list = [methane_ff]

# Tell Cassandra to add 100 methane at the start
mols_to_add = [[100]]

# Create the System and MoveSet
system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
moveset = mc.MoveSet("npt", species_list)

# Run the Monte Carlo simulation
mc.run(
    system=system,
Exemple #15
0
    def populate(self, compound_dict=None, x=1, y=1, z=1):
        """Expand lattice and create compound from lattice.

        Expands lattice based on user input. The user must also
        pass in a dictionary that contains the keys that exist in the
        basis_dict. The corresponding Compound will be the full lattice
        returned to the user.

        If no dictionary is passed to the user, Dummy Compounds will be used.

        Parameters
        ----------
        x : int, optional, default=1
            How many iterations in the x direction.
        y : int, optional, default=1
            How many iterations in the y direction.
        z : int, optional, default=1
            How many iterations in the z direction.
        compound_dict : dictionary, optional, default=None
            Link between basis_dict and Compounds.

        Exceptions Raised
        -----------------
        ValueError : incorrect x,y, or z values.
        TypeError : incorrect type for basis vector

        Call Restrictions
        -----------------
        Called after constructor by user.

        """

        x, y, z = self._sanitize_populate_args(x=x, y=y, z=z)

        if ((isinstance(compound_dict, dict)) or (compound_dict is None)):
            pass
        else:
            raise TypeError('Compound dictionary is not of type dict. '
                            '{} was passed.'.format(type(compound_dict)))

        cell = defaultdict(list)
        [a, b, c] = self.lattice_spacing

        transform_mat = self.lattice_vectors
        # Unit vectors
        transform_mat = np.asarray(transform_mat, dtype=np.float64)
        transform_mat = np.reshape(transform_mat, newshape=(3,3))
        norms = np.linalg.norm(transform_mat, axis=1)

        # Normalized vectors for change of basis
        unit_vecs = np.divide(transform_mat.transpose(), norms)

        # Generate new coordinates
        for key, locations in self.lattice_points.items():
            for coords in locations:
                for replication in it.product(range(x), range(y), range(z)):

                    new_coords = np.asarray(coords, dtype=np.float64)
                    new_coords = np.reshape(new_coords, (1, 3), order='C')

                    new_coords[0][0] = new_coords[0][0] + replication[0]
                    new_coords[0][1] = new_coords[0][1] + replication[1]
                    new_coords[0][2] = new_coords[0][2] + replication[2]

                    # Change of basis to cartesian
                    new_coords = np.dot(unit_vecs, new_coords.transpose())

                    new_coords[0] = new_coords[0] * a
                    new_coords[1] = new_coords[1] * b
                    new_coords[2] = new_coords[2] * c
                    new_coords = np.reshape(new_coords, (1, 3), order='C')

                    tuple_of_coords = tuple(new_coords.flatten())
                    cell[key].append(tuple_of_coords)

        ret_lattice = mb.Compound()

        # Create (clone) a mb.Compound for the newly generate positions
        if compound_dict is None:
            for key_id, all_pos in cell.items():
                particle = mb.Compound(name=key_id, pos=[0, 0, 0])
                for pos in all_pos:
                    particle_to_add = mb.clone(particle)
                    particle_to_add.translate_to(list(pos))
                    ret_lattice.add(particle_to_add)
        else:
            for key_id, all_pos in cell.items():
                if isinstance(compound_dict[key_id], mb.Compound):
                    compound_to_move = compound_dict[key_id]
                    for pos in all_pos:
                        tmp_comp = mb.clone(compound_to_move)
                        tmp_comp.translate_to(list(pos))
                        ret_lattice.add(tmp_comp)
                else:
                    err_type = type(compound_dict.get(key_id))
                    raise TypeError('Invalid type in provided Compound '
                                    'dictionary. For key {}, type: {} was '
                                    'provided, not mbuild.Compound.'
                                    .format(key_id, err_type))
        # set periodicity, currently assuming rectangular system
        if not np.all(np.allclose(self.angles, [90.0, 90.0, 90.0])):
            warn('Periodicity of non-rectangular lattices are not valid with '
                 'default boxes. Only rectangular lattices are valid '
                 'at this time.')
        ret_lattice.periodicity = np.asarray([a * x, b * y, c * z], dtype=np.float64)

        # if coordinates are below a certain threshold, set to 0
        tolerance = 1e-12
        ret_lattice.xyz_with_ports[ret_lattice.xyz_with_ports <= tolerance] = 0.

        return ret_lattice
Exemple #16
0
    """
    def __init__(self,
                 lattice_spacing=None,
                 compound_to_add=None,
                 x=1,
                 y=1,
                 z=1):
        super(FCC, self).__init__()
        lattice_points = {
            'A': [[0, 0, 0], [0, 0.5, 0.5], [0.5, 0.5, 0], [0.5, 0, 0.5]]
        }
        angles = [90, 90, 90]

        fcc_lattice = mbuild.Lattice(lattice_spacing=lattice_spacing,
                                     angles=angles,
                                     lattice_points=lattice_points)
        self.add(
            fcc_lattice.populate(x=x,
                                 y=y,
                                 z=z,
                                 compound_dict={'A': compound_to_add}))


if __name__ == "__main__":
    au_fcc_lattice = FCC(lattice_spacing=0.40782,
                         compound_to_add=mbuild.Compound(name="Au"),
                         x=5,
                         y=5,
                         z=1)
    print(au_fcc_lattice)
 def test_incorrect_populate_inputs(self, x, y, z):
     with pytest.raises(ValueError):
         test_lattice = mb.Lattice(lattice_spacing=[1, 1, 1])
         test_lattice.populate(
             compound_dict={"id": mb.Compound()}, x=x, y=y, z=z
         )
Exemple #18
0
def create_system(
        pore_width,
        n_ion_pairs,
        n_water,
        pve_ion=mbuild.Compound(name="Na"),
        nve_ion=mbuild.Compound(name="Cl"),
        engine="cassandra",
):
    """Create a system with a graphene pore filled with n_ion_pairs,
    (na, cl), and n_water spce water molecules.

    Parameters
    ----------
    pore_width : u.unyt_quantity (length)
        width of pore for restricted insertions
    n_ion_pairs : int
        number of na, cl ion pairs
    n_water : int
        number of water molecules
    pve_ion : mbuild.Compound, optional, default=Na
        positive ion
    nve_ion : mbuild.Compound, optional, default=Cl
        negative ion
    engine : str, optional, default="cassandra"
        engine system is being initialized for, determines how box is created

    Returns
    -------
    filled_pore : mbuild.Compound
    """

    if n_ion_pairs == 0:
        filled_pore = mbuild.recipes.GraphenePoreSolvent(
            pore_length=2.3,
            pore_depth=2.2,
            pore_width=pore_width.to_value("nm"),
            n_sheets=3,
            slit_pore_dim=2,
            x_bulk=0,
            solvent=spce_water,
            n_solvent=n_water,
        )
    else:
        # Create pore system
        filled_pore = mbuild.recipes.GraphenePoreSolvent(
            pore_length=2.3,
            pore_depth=2.2,
            pore_width=pore_width.to_value("nm"),
            n_sheets=3,
            slit_pore_dim=2,
            x_bulk=0,
            solvent=[pve_ion, nve_ion, spce_water],
            n_solvent=[n_ion_pairs, n_ion_pairs, n_water],
        )

    # Translate to centered at 0,0,0 and make box larger in z
    if engine == 'cassandra':
        box_center = filled_pore.periodicity / 2.0
        filled_pore.translate(-box_center)

    return filled_pore
Exemple #19
0
 def test_remove_no_bond_graph(self):
     compound = mb.Compound()
     particle = mb.Compound(name='C', pos=[0, 0, 0])
     compound.add(particle, 'test-particle')
     compound.remove(particle)
     assert particle not in compound.particles()
Exemple #20
0
import mbuild as mb
from mbuild.formats.lammpsdata import write_lammpsdata

import scripts.bilayer as bilayer

# Import statements for molecule prototypes
import atomistic.dppc.DPPC as DPPC
import atomistic.c24ffa.ffa24 as ffa24
import atomistic.tip3p.SOL as SOL

###################
## Sample script to convert a GROMACS structure to a
## fully-parameterized LAMMPS system
####################

system = mb.Compound()
for i in range(72):
    system.add(DPPC.DPPC(use_atom_name=False))

for i in range(2160):
    system.add(SOL.SOL(use_atom_name=False))
system.update_coordinates('wrapped.gro')

# In order to avoid using smarts, define custom elements in parmed
# by adding underscores to mb particle names
for num, i in enumerate(system.particles()):
    i.name = "_{}".format(i.name)

structure = system.to_parmed(box=system.boundingbox,
                             residues=set(
                                 [p.parent.name for p in system.particles()]))
Exemple #21
0
 def test_min_periodic_dist(self, ethane):
     compound = mb.Compound(ethane)
     C_pos = np.array([atom.pos for atom in list(compound.particles_by_name('C'))])
     assert round(compound.min_periodic_distance(C_pos[0], C_pos[1]), 2) == 0.14
     compound.periodicity = np.array([0.2, 0.2, 0.2])
     assert round(compound.min_periodic_distance(C_pos[0], C_pos[1]), 2) == 0.06
 def methane_trappe(self):
     trappe = foyer.forcefields.load_TRAPPE_UA()
     methane = mbuild.Compound(pos=[0.0, 0.0, 0.0], name="_CH4")
     methane = trappe.apply(methane)
     return methane
Exemple #23
0
 def test_save_resnames_single(self, c3, n4):
     system = mb.Compound([c3, n4])
     system.save('resnames_single.gro', residues=['C3', 'N4'])
     struct = pmd.load_file('resnames_single.gro')
     assert struct.residues[0].number ==  1
     assert struct.residues[1].number ==  2
 def wrongbox(self):
     box = mbuild.Compound()
     box.boundingbox.lengths = [5.0, 5.0, 5.0]
     return box
Exemple #25
0
    def methane_ua_gomc(self):
        methane_ua_gomc = mb.Compound(name="_CH4")

        return methane_ua_gomc
Exemple #26
0
def from_mbuild(compound, box=None, search_method=element_by_symbol):
    """Convert an mbuild.Compound to a gmso.Topology.

    This conversion makes the following assumptions about the inputted `Compound`:

        * All positional and box dimension values in compound are in nanometers.

        * If the `Compound` has 4 or more levels of hierarchy, these are\
          compressed to 3 levels of hierarchy in the resulting `Topology`. The\
          top level `Compound` becomes the `Topology`, the second level\
          Compounds become `SubTopologies`, and each particle becomes a `Site`,\
          which are added to their corresponding `SubTopologies`.

        * Furthermore, `Sites` that do not belong to a sub-`Compound` are\
          added to a single-`Site` `SubTopology`.

        * The box dimension are extracted from `compound.periodicity`. If\
          the `compound.periodicity` is `None`, the box lengths are the lengths of\
          the bounding box + a 0.5 nm buffer.

        * Only `Bonds` are added for each bond in the `Compound`. If `Angles`\
          and `Dihedrals` are desired in the resulting `Topology`, they must be\
          added separately from this function.

    Parameters
    ----------
    compound : mbuild.Compound
        mbuild.Compound instance that need to be converted
    box : mbuild.Box, optional, default=None
        Box information to be loaded to a gmso.Topology
    search_method : function, optional, default=element_by_symbol
        Searching method used to assign element from periodic table to
        particle site.
        The information specified in the `search_method` argument is extracted
        from each `Particle`'s `name` attribute.
        Valid functions are element_by_symbol, element_by_name,
        element_by_atomic_number, and element_by_mass, which can be imported
        from `gmso.core.element'

    Returns
    -------
    top : gmso.Topology
    """
    msg = "Argument compound is not an mbuild.Compound"
    assert isinstance(compound, mb.Compound), msg

    top = Topology()
    top.typed = False

    # Keep the name if it is not the default mBuild Compound name
    if compound.name != mb.Compound().name:
        top.name = compound.name

    site_map = dict()
    for child in compound.children:
        if len(child.children) == 0:
            continue
        else:
            subtop = SubTopology(name=child.name)
            top.add_subtopology(subtop, update=False)
            for particle in child.particles():
                pos = particle.xyz[0] * u.nanometer
                ele = search_method(particle.name)
                site = Atom(name=particle.name, position=pos, element=ele)
                site_map[particle] = site
                subtop.add_site(site, update_types=False)

    for particle in compound.particles():
        already_added_site = site_map.get(particle, None)
        if already_added_site:
            continue

        pos = particle.xyz[0] * u.nanometer
        ele = search_method(particle.name)
        site = Atom(name=particle.name, position=pos, element=ele)
        site_map[particle] = site

        # If the top has subtopologies, then place this particle into
        # a single-site subtopology -- ensures that all sites are in the
        # same level of hierarchy.
        if len(top.subtops) > 0:
            subtop = SubTopology(name=particle.name)
            top.add_subtopology(subtop)
            subtop.add_site(site, update_types=False)
        else:
            top.add_site(site, update_types=False)

    for b1, b2 in compound.bonds():
        new_bond = Bond(connection_members=[site_map[b1], site_map[b2]],
                        bond_type=None)
        top.add_connection(new_bond, update_types=False)
    top.update_topology()

    if box:
        top.box = from_mbuild_box(box)
    # Assumes 2-D systems are not supported in mBuild
    # if compound.periodicity is None and not box:
    else:
        if compound.box:
            top.box = from_mbuild_box(compound.box)
        else:
            top.box = from_mbuild_box(compound.get_boundingbox())
    top.periodicity = compound.periodicity

    return top
Exemple #27
0
 def test_init_with_subcompounds2(self, ethane, h2o):
     compound = mb.Compound([ethane, h2o])
     assert compound.n_particles == 8 + 3
     assert compound.n_bonds == 7 + 2
Exemple #28
0
def run_gemc(**custom_args):

    # Use mbuild to create molecules
    methane = mbuild.Compound(name="_CH4")

    # Create two empty mbuild.Box
    # (vapor = larger, liquid = smaller)
    liquid_box = mbuild.Box(lengths=[3.0, 3.0, 3.0])
    vapor_box = mbuild.Box(lengths=[4.0, 4.0, 4.0])

    # Load forcefields
    trappe = foyer.forcefields.load_TRAPPE_UA()

    # Use foyer to apply forcefields
    typed_methane = trappe.apply(methane)

    # Create box and species list
    box_list = [liquid_box, vapor_box]
    species_list = [typed_methane]

    mols_to_add = [[350], [100]]

    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    moveset = mc.MoveSet("gemc", species_list)

    moveset.prob_volume = 0.010
    moveset.prob_swap = 0.11

    thermo_props = [
        "energy_total",
        "energy_intervdw",
        "pressure",
        "volume",
        "nmols",
        "mass_density",
    ]

    default_args = {
        "run_name": "equil",
        "charge_style": "none",
        "rcut_min": 2.0 * u.angstrom,
        "vdw_cutoff": 14.0 * u.angstrom,
        "units": "sweeps",
        "steps_per_sweep": 450,
        "coord_freq": 50,
        "prop_freq": 10,
        "properties": thermo_props,
    }

    # Combine default/custom args and override default
    custom_args = {**default_args, **custom_args}

    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=250,
        temperature=151.0 * u.K,
        **custom_args,
    )

    # Update run_name and restart_name
    custom_args["run_name"] = "prod"
    custom_args["restart_name"] = "equil"

    mc.restart(
        system=system,
        moveset=moveset,
        run_type="production",
        run_length=750,
        temperature=151.0 * u.K,
        **custom_args,
    )
Exemple #29
0
 def test_init_with_bad_name(self):
     with pytest.raises(ValueError):
         mb.Compound(name=1)
Exemple #30
0
def construct_system(dist_from_sheet=0.7,
                     box_thickness=0.5,
                     n_load_per_side=10,
                     bilayer_center=[5.387, 5.347, 3.26]):
    """ Build graphene + sds + bilayer + ions
    The idea is to pack a box below the sheet and below the sheet.
    The density of SDS is 1.01 g/cm$^3$, which equates to 2.109 molecules/nm$^3$
    The box we are filling is about 5nm x 5nm x 0.635nm. 
    At max SDS density, this is 33.5 molecules of SDS

    Parameters
    ---------
    dist_from_sheet : float, default 0.7 nm
        When defining the box above/below the sheet, specify how far above/below
    box_thickness : float: default 0.5nm
        When defining the box to fill, the X and Y dimensions take from
        the graphene sheet, but the Z dimensions (thickness) is defined 
        in box_thickneess
    n_load_per_side : int, default 10
        Important for packing the boxes and specifying number of SDS (and Na ions)
        to add to the system

    """

    header = """; Include forcefield parameters
#include "/raid6/homes/ahy3nz/Programs/graphene_build/force-field/ffmix.itp"
#include "/raid6/homes/ahy3nz/Programs/graphene_build/force-field/molecules.itp"
#include "/raid6/homes/ahy3nz/Programs/graphene_build/force-field/ions.itp
    """

    gra = mb.load(os.path.join(PATH_TO_MOLECULES, 'sheet.gro'))
    gra.name = 'GRA_5'

    sds = mb.load(os.path.join(PATH_TO_MOLECULES, 'SDS.gro'))
    sds.name = 'SDS'
    # The SDS molecules are initially aligned with the Z-axis, so do a rotation
    sds.spin(np.pi / 2, [1, 0, 0])

    na_part = mb.Particle(name="NA")
    na = mb.Compound()
    na.name = "NA"
    na.add(na_part)

    above_box = mb.Box(mins=np.min(gra.xyz, axis=0) + [0, 0, dist_from_sheet],
                       maxs=np.max(gra.xyz, axis=0) +
                       [0, 0, dist_from_sheet + box_thickness])
    fill_above = fill_box([sds, na],
                          n_compounds=[n_load_per_side, n_load_per_side],
                          box=above_box,
                          edge=0.1,
                          overlap=0.1)

    below_box = mb.Box(mins=np.min(gra.xyz, axis=0) -
                       [0, 0, dist_from_sheet + box_thickness],
                       maxs=np.max(gra.xyz, axis=0) - [0, 0, dist_from_sheet])
    fill_below = fill_box([sds, na],
                          n_compounds=[n_load_per_side, n_load_per_side],
                          box=below_box,
                          edge=0.1,
                          overlap=0.1)

    sys = mb.Compound()
    sys.add([gra, fill_above, fill_below])

    sys.spin(np.pi / 2, [1, 0, 0])  # Do some rotations to get it corner first
    sys.spin(np.pi / 4, [0, 1, 0])
    sys.translate_to(bilayer_center)  # This is the bilayer center
    sys.translate([0, 0, 6])  # Shift the loaded GNF up to be above the bialyer

    # For the sake of writing, we will be using a lot of mdtraj functionality
    traj = sys.to_trajectory(residues=['GRA_5', 'SDS', 'NA'])
    bilayer = mdtraj.load(os.path.join(PATH_TO_MOLECULES, 'bilayer.gro'))
    composite_traj = traj.stack(bilayer)
    composite_traj.unitcell_lengths = bilayer.unitcell_lengths
    composite_traj.unitcell_lengths[0, 2] = 13
    composite_traj[0].save('composite.gro')
    write_gmx_topology('topol.top', composite_traj, header=header)

    # Use external module to perform rotations and write pulling MDP
    graphene_rotations.rotate_gnf_write_mdp(gro_file='composite.gro',
                                            angle_of_attack=0,
                                            force_constant=50,
                                            outgro='composite_rotated.gro')