Esempio n. 1
0
    def __init__(self, chain_length):
        """Initialize an Alkane Compound.

        Parameters
        ----------
        chain_length : int
            Length of the alkane chain (in number of carbons)
        """
        # Make sure the user inputs a chain length of at least 1
        if chain_length < 1:
            raise ValueError('Chain length must be greater than 1')

        super(Alkane, self).__init__()

        # Create a polymer of CH2 units
        chain = mb.recipes.Polymer(CH2(), n=chain_length, port_labels=('up', 'down'))
        self.add(chain, 'chain')

        # Cap one end of the polymer with a hydrogen
        self.add(H(), 'up_cap')
        mb.force_overlap(move_this=self['up_cap'],
                         from_positions=self['up_cap']['up'],
                         to_positions=self['chain']['up'])

        # Cap the other end of the polymer with a hydrogen
        self.add(H(), 'down_cap')
        mb.force_overlap(move_this=self['down_cap'],
                         from_positions=self['down_cap']['up'],
                         to_positions=self['chain']['down'])
Esempio n. 2
0
    def __init__(self, pattern, tile_x=1, tile_y=1, chain_length=10):
        """Create an alkylsilane monolayer on beta-cristobalite.

        Parameters
        ----------
        pattern : np.ndarray, shape=(n, 3), optional, default=None
            An array of planar binding locations. If not provided, the entire
            surface will be filled with `chain`.
        tile_x : int, optional, default=1
            Number of times to replicate substrate in x-direction.
        tile_y : int, optional, default=1
            Number of times to replicate substrate in y-direction.
        chain_length : int, optional, default=10
            Number of carbon atoms per chain.
        """
        surface = Betacristobalite()
        alkylsilane = AlkylSilane(chain_length)
        hydrogen = H()
        super(AlkaneMonolayer, self).__init__(surface,
                                              alkylsilane,
                                              backfill=hydrogen,
                                              pattern=pattern,
                                              tile_x=tile_x,
                                              tile_y=tile_y)


# -- ==alkane_monolayer== --
Esempio n. 3
0
    def test_monolayer(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)

        chain = mb.Polymer(ch2, n=10)
        monolayer = mb.Monolayer(surface=Betacristobalite(),
                                 chains=chain,
                                 backfill=H(),
                                 pattern=pattern)

        assert monolayer.n_particles == 1900 + n * m * (10 * 3) + (100 - n * m)
        assert monolayer.n_bonds == 2400 + n * m * (10 * 2 + 9 + 1) + (100 -
                                                                       n * m)
 def __init__(self,
              pattern,
              tile_x=1,
              tile_y=1,
              chain_length=4,
              alpha=pi / 4):
     surface = Betacristobalite()
     brush = Brush(chain_length=chain_length, alpha=alpha)
     hydrogen = H()
     super(PMPCLayer, self).__init__(surface,
                                     brush,
                                     backfill=hydrogen,
                                     pattern=pattern,
                                     tile_x=tile_x,
                                     tile_y=tile_y)
Esempio n. 5
0
def main(args):
    length = 2
    backbone = args.backbone
    locations = [0]
    terminal_group = args.terminal_group

    cpa = AlkylsilaneInternal(chain_length=length, internal_group=backbone, locations=locations, terminal_group=terminal_group)
    h = H()
    compound = mb.Compound()
    compound.add(cpa, 'cpa')
    compound.add(h, 'h')
    mb.force_overlap(compound['cpa'], compound['cpa'].all_ports()[0], compound['h'].all_ports()[0])

    structure = cpa.to_parmed(box=None, residues=['chain'])
    ff = Forcefield(forcefield_files='../shearing-code/src/util/forcefield/oplsaa.xml')
    structure_ = ff.apply(structure)
Esempio n. 6
0
    def test_monolayer(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)

        chain = mb.recipes.Polymer(monomers=[ch2])
        chain.build(n=10, add_hydrogens=False)
        monolayer = mb.recipes.Monolayer(
            surface=Betacristobalite(),
            chains=chain,
            backfill=H(),
            pattern=pattern,
        )

        assert monolayer.n_particles == 2000 + n * m * 29
        assert monolayer.n_bonds == 2500 + n * m * 29
Esempio n. 7
0
    def test_pattern_kwargs(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)

        chain = mb.Polymer(ch2, n=10)
        monolayer = mb.Monolayer(surface=Betacristobalite(),
                                 chains=H(),
                                 guest_port_name='up',
                                 backfill=chain,
                                 backfill_port_name='down',
                                 pattern=pattern)

        chains = 100 - (n * m)

        assert monolayer.n_particles == 1900 + chains * (10 * 3) + (100 -
                                                                    chains)
        assert monolayer.n_bonds == 2400 + chains * (10 * 2 + 9 + 1) + (100 -
                                                                        chains)
Esempio n. 8
0
def initialize(job):
    "Initialize the simulation configuration."
    from pkg_resources import resource_filename

    from mbuild.lib.atoms import H

    from atools.fileio import write_monolayer_ndx
    from atools.lib.chains import Alkylsilane
    from atools.recipes import DualSurface, SilicaInterface, SurfaceMonolayer
    from atools.structure import identify_rigid_groups

    with job:
        chainlength = job.statepoint()['chainlength']
        n_chains = job.statepoint()['n']
        seed = job.statepoint()['seed']
        terminal_group = job.statepoint()['terminal_group']

        surface = SilicaInterface(thickness=1.2, seed=seed)
        chain_proto = Alkylsilane(chain_length=chainlength,
                                  terminal_group=terminal_group)
        monolayer = SurfaceMonolayer(surface=surface,
                                     chains=chain_proto,
                                     n_chains=n_chains,
                                     seed=seed,
                                     backfill=H())
        dual_monolayer = DualSurface(monolayer)
        box = dual_monolayer.boundingbox
        dual_monolayer.periodicity += np.array([0, 0, 5. * box.lengths[2]])

        forcefield_dir = resource_filename('atools', 'forcefields')
        dual_monolayer.save('init.gro',
                            forcefield_files=os.path.join(
                                forcefield_dir, 'oplsaa-silica.xml'),
                            overwrite=True)
        dual_monolayer.save('init.top',
                            forcefield_files=os.path.join(
                                forcefield_dir, 'oplsaa-silica.xml'),
                            overwrite=True)
        rigid_groups = identify_rigid_groups(monolayer=dual_monolayer,
                                             terminal_group=terminal_group,
                                             freeze_thickness=0.5)
        write_monolayer_ndx(rigid_groups=rigid_groups, filename='init.ndx')
Esempio n. 9
0
    def test_mixed_monolayer(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)
        fractions = [0.75, 0.25]

        chain_a = mb.Polymer(ch2, n=5)
        chain_b = mb.Polymer(ch2, n=15)
        monolayer = mb.Monolayer(surface=Betacristobalite(),
                                 chains=[chain_a, chain_b],
                                 fractions=fractions,
                                 backfill=H(),
                                 pattern=pattern)

        n_a = round(n * m * 0.75)
        n_b = round(n * m * 0.25)
        assert monolayer.n_particles == 1900 + n_a * 5 * 3 + n_b * 15 * 3 + (
            100 - (n_a + n_b))
        assert monolayer.n_bonds == 2400 + n_a * (5 * 2 + 4 + 1) + n_b * (
            15 * 2 + 14 + 1) + (100 - (n_a + n_b))
Esempio n. 10
0
    def test_pattern_kwargs(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)

        chain = mb.recipes.Polymer(monomers=[ch2])
        chain.build(n=10, add_hydrogens=False)

        monolayer = mb.recipes.Monolayer(
            surface=Betacristobalite(),
            chains=H(),
            guest_port_name="up",
            backfill=chain,
            backfill_port_name="down",
            pattern=pattern,
        )

        chains = 100 - (n * m)

        assert monolayer.n_particles == 2000 + chains * 29
        assert monolayer.n_bonds == 2500 + chains * 29
Esempio n. 11
0
    def test_mixed_monolayer(self, ch2):
        n = 8
        m = 8
        pattern = mb.Grid2DPattern(n, m)
        fractions = [0.75, 0.25]

        chain_a = mb.recipes.Polymer(monomers=[ch2])
        chain_a.build(n=5, add_hydrogens=False)

        chain_b = mb.recipes.Polymer(monomers=[ch2])
        chain_b.build(n=15, add_hydrogens=False)

        monolayer = mb.recipes.Monolayer(
            surface=Betacristobalite(),
            chains=[chain_a, chain_b],
            fractions=fractions,
            backfill=H(),
            pattern=pattern,
        )

        n_a = round(n * m * 0.75)
        n_b = round(n * m * 0.25)
        assert monolayer.n_particles == 2000 + n_a * 14 + n_b * 44
        assert monolayer.n_bonds == 2500 + n_a * 14 + n_b * 44
Esempio n. 12
0
    def __init__(self, chain_length, internal_group, locations):
        super(Alkylsilane, self).__init__()

        hmodule = __import__('atools.lib.moieties.multiple_ports.' +
                             internal_group)
        hclass_ = getattr(hmodule.lib.moieties.multiple_ports,
                          internal_group.title())
        hgroup = hclass_()

        # Determine alkane segments
        if isinstance(locations, int):
            locations = [locations]
        locations.sort()

        silane = Silane()
        self.add(silane, 'silane')
        self.add(silane['down'], 'down', containment=False)

        if 0 in locations:
            '''
            self.add(hgroup, 'hgroup')
            mb.force_overlap(self['silane'], self['silane']['up'], 
                             self['hgroup']['down'])
            '''
            current_segment = silane
        else:
            first_length = locations[0]
            first_segment = Alkane(first_length,
                                   cap_front=False,
                                   cap_end=False)
            self.add(first_segment, 'bottom_chain')
            mb.force_overlap(self['silane'], self['silane']['up'],
                             self['bottom_chain']['down'])
            current_segment = first_segment

        c_remove = 0
        if internal_group in ['amide', 'hemiacetal']:
            c_remove += 1

        for i, loc in enumerate(locations[1:]):
            hgroup_clone = mb.clone(hgroup)
            self.add(hgroup_clone, 'hgroup{}'.format(i + 1))
            mb.force_overlap(self['hgroup{}'.format(i + 1)],
                             self['hgroup{}'.format(i + 1)]['down'],
                             current_segment['up'])
            current_segment = hgroup_clone
            length = loc - locations[i] - 1 - c_remove
            if length > 0:
                segment = Alkane(length, cap_front=False, cap_end=False)
                self.add(segment, 'internal_chain{}'.format(i + 1))
                current_segment = segment
                mb.force_overlap(
                    self['internal_chain{}'.format(i + 1)],
                    self['internal_chain{}'.format(i + 1)]['down'],
                    self['hgroup{}'.format(i + 1)]['up'])

        self.add(hgroup, 'hgroup')
        mb.force_overlap(self['hgroup'], self['hgroup']['down'],
                         current_segment['up'])

        last_length = chain_length - locations[-1] - 1 - c_remove
        if last_length:
            last_segment = Alkane(last_length, cap_front=True, cap_end=False)
            self.add(last_segment, 'top_chain')
            mb.force_overlap(self['top_chain'], self['top_chain']['down'],
                             self['hgroup']['up'])
        else:
            hydrogen = H()
            self.add(hydrogen, 'H-cap')
            mb.force_overlap(self['H-cap'], self['H-cap']['up'],
                             self['hgroup']['up'])
Esempio n. 13
0
 def hydrogen(self):
     from mbuild.lib.atoms import H
     return H()
Esempio n. 14
0
def initialize(job):
    "Initialize the simulation configuration."
    '''
    ---------------------------
    Read statepoint information
    ---------------------------
    '''
    chainlength = job.statepoint()['chainlength']
    n_chains = job.statepoint()['n']
    seed = job.statepoint()['seed']
    terminal_group = job.statepoint()['terminal_group']
    '''
    -----------------------------------
    Generate amorphous silica interface
    -----------------------------------
    '''
    surface = SilicaInterface(thickness=1.2, seed=seed)
    '''
    ------------------------------------------------------
    Generate prototype of functionalized alkylsilane chain
    ------------------------------------------------------
    '''
    chain_prototype = Alkylsilane(chain_length=chainlength,
                                  terminal_group=terminal_group)
    '''
    ----------------------------------------------------------
    Create monolayer on surface, backfilled with hydrogen caps
    ----------------------------------------------------------
    '''
    monolayer = SurfaceMonolayer(surface=surface,
                                 chains=chain_prototype,
                                 n_chains=n_chains,
                                 seed=seed,
                                 backfill=H(),
                                 rotate=False)
    '''
    ------------------------------------------
    Duplicate to yield two opposing monolayers
    ------------------------------------------
    '''
    dual_monolayer = DualSurface(monolayer, separation=2.0)
    '''
    --------------------------------------------------------
    Make sure box is elongated in z to be pseudo-2D periodic
    --------------------------------------------------------
    '''
    box = dual_monolayer.boundingbox
    dual_monolayer.periodicity += np.array([0, 0, 5. * box.lengths[2]])
    '''
    -------------------------------------------------------------------
    - Save to .GRO, .TOP, and .LAMMPS formats
    - Atom-type the system using Foyer, with parameters from the OPLS
      force field obtained from GROMACS. Parameters are located in a
      Foyer XML file in the `atools` git repo, with references provided
      as well as notes where parameters have been added or altered to
      reflect the literature.
    -------------------------------------------------------------------
    '''
    forcefield_dir = resource_filename('atools', 'forcefields')
    dual_monolayer.save('init.gro', overwrite=True)
    dual_monolayer.save('init.top',
                        forcefield_files=os.path.join(forcefield_dir,
                                                      'oplsaa.xml'),
                        combining_rule='geometric',
                        overwrite=True)
    dual_monolayer.save('init.lammps',
                        forcefield_files=os.path.join(forcefield_dir,
                                                      'oplsaa.xml'),
                        combining_rule='geometric',
                        overwrite=True)
    '''
    --------------------------------------
    Specify index groups and write to file
    --------------------------------------
    '''
    index_groups = generate_index_groups(system=dual_monolayer,
                                         terminal_group=terminal_group,
                                         freeze_thickness=0.5)
    write_monolayer_ndx(rigid_groups=index_groups, filename='init.ndx')
Esempio n. 15
0
def initialize_system(job):
    """ Generate the monolayer surfaces, parametrize, save LAMMPS, GRO, TOP.
    """
    """
    ---------------------------
    Read statepoint information
    ---------------------------
    """
    chainlength_a = job.statepoint()["chainlength_a"]
    chainlength_b = job.statepoint()["chainlength_b"]
    chainlength_c = job.statepoint()["chainlength_c"]
    chainlength_d = job.statepoint()["chainlength_d"]
    seed = job.statepoint()["seed"]
    pattern_type = job.statepoint()["pattern_type"]
    terminal_groups = job.statepoint()["terminal_groups"]
    a_fraction = job.statepoint()["fraction_a"]
    c_fraction = job.statepoint()["fraction_c"]
    num_chains = job.statepoint()["n"]
    backbone_1 = job.statepoint()["backbone_1"]
    backbone_2 = job.statepoint()["backbone_2"]
    locations = job.statepoint()["locations"]
    """
    -----------------------------------
    Generate amorphous silica interface
    -----------------------------------
    """
    surface_a = SilicaInterface(thickness=1.2, seed=seed)
    surface_b = SilicaInterface(thickness=1.2, seed=seed)

    """
    ------------------------------------------------------
    Generate prototype of functionalized alkylsilane chain
    ------------------------------------------------------
    """
    chain_prototype_a = AlkylsilaneInternalplus(
        chain_length=chainlength_a, internal_group=backbone_1, locations=locations, terminal_group=terminal_groups[0]
    )
    chain_prototype_b = AlkylsilaneInternalplus(
        chain_length=chainlength_b, internal_group=backbone_2, locations=locations, terminal_group=terminal_groups[1]
    )
    chain_prototype_c = AlkylsilaneInternalplus(
        chain_length=chainlength_c, internal_group=backbone_1, locations=locations, terminal_group=terminal_groups[2]
    )
    chain_prototype_d = AlkylsilaneInternalplus(
	chain_length=chainlength_d, internal_group=backbone_2, locations=locations, terminal_group=terminal_groups[3]
    )
    """
    ----------------------------------------------------------
    Create monolayer on surface, backfilled with hydrogen caps
    ----------------------------------------------------------
    """
    # bottom monolayer is backfilled with the other terminal group
    # num_chains = num_chains * a_fraction
    monolayer_a = SurfaceMonolayer(
        surface=surface_a,
        chains=[chain_prototype_a, chain_prototype_b],
        n_chains=num_chains,
        seed=seed,
        backfill=H(),
        rotate=False,
        fractions=[a_fraction, 1.0 - a_fraction],
    )
    monolayer_a.name = "Bottom"
    monolayer_b = SurfaceMonolayer(
        surface=surface_b,
        chains=[chain_prototype_c, chain_prototype_d],
        n_chains=num_chains,
        seed=seed,
        backfill=H(),
        rotate=False,
	fractions=[c_fraction, 1.0 - c_fraction],
    )
    monolayer_b.name = "Top"

    """
    ------------------------------------------
    Duplicate to yield two opposing monolayers
    ------------------------------------------
    """
    dual_monolayer = DualSurface(
        bottom=monolayer_a, top=monolayer_b, separation=2.0
    )

    """
    --------------------------------------------------------
    Make sure box is elongated in z to be pseudo-2D periodic
    --------------------------------------------------------
    """
    box = dual_monolayer.boundingbox
    dual_monolayer.periodicity += np.array([0, 0, 5.0 * box.lengths[2]])

    """
    -------------------------------------------------------------------
    - Save to .GRO, .TOP, and .LAMMPS formats
    - Atom-type the system using Foyer, with parameters from the OPLS
    force field obtained from GROMACS. Parameters are located in a
    Foyer XML file in the `atools` git repo, with references provided
    as well as notes where parameters have been added or altered to
    reflect the literature.
    -------------------------------------------------------------------
    """
    # path for project root dir
    proj = signac.get_project()
    forcefield_filepath = pathlib.Path(
        proj.root_directory() + "/src/util/forcefield/oplsaa.xml"
    )
    # change into job directoryA
    _switch_dir(job)
    logging.info("at dir: {}".format(job.ws))
    for p in dual_monolayer.particles():
        if p.name == "OS":
            p.name = "O"
    dual_monolayer.save("init.gro", residues=["Top", "Bottom"], overwrite=True)

    
            
            
    if not (
        job.isfile("init.top")
        and job.isfile("init.lammps")
        and job.isfile("init.gro")
    ):

        structure = dual_monolayer.to_parmed(
            box=None, residues=["Top", "Bottom"]
        )
        ff = Forcefield(forcefield_files=forcefield_filepath.as_posix())
        structure = ff.apply(structure)
        structure.combining_rule = "geometric"

        structure.save("init.top", overwrite=True)
        write_lammpsdata(filename="init.lammps", structure=structure, detect_forcefield_style=False)

        """
        --------------------------------------
        Specify index groups and write to file
        --------------------------------------
        """
    index_groups = generate_index_groups(
        system=dual_monolayer,
        terminal_groups=terminal_groups,
        freeze_thickness=0.5,
    )
    write_monolayer_ndx(rigid_groups=index_groups, filename="init.ndx")
Esempio n. 16
0
    def build(self, n, sequence="A", add_hydrogens=True):
        """Connect one or more components in a specified sequence.

        Uses the compounds that are stored in Polymer.monomers and
        Polymer.end_groups.

        Parameters
        ----------
        n : int
            The number of times to replicate the sequence.
        sequence : str, optional, default 'A'
            A string of characters where each unique character represents one
            repetition of a monomer. Characters in `sequence` are assigned to
            monomers in the order they appear in `Polymer.monomers`.
            The characters in `sequence` are assigned to the compounds in the
            in the order that they appear in the Polymer.monomers list.
            For example, 'AB' where 'A'corresponds to the first compound
            added to Polymer.monomers and 'B' to the second compound.
        add_hydrogens : bool, default True
            If True and an end group compound is None, then the head or tail
            of the polymer will be capped off with hydrogen atoms. If end group
            compounds exist, then they will be used.
            If False and an end group compound is None, then the head or tail
            port will be exposed in the polymer.
        """
        if n < 1:
            raise ValueError("n must be 1 or more")
        n_monomers = n * len(sequence)

        for monomer in self._monomers:
            for label in self._port_labels:
                assert_port_exists(label, monomer)

        unique_seq_ids = sorted(set(sequence))

        if len(self._monomers) != len(unique_seq_ids):
            raise ValueError(
                "Number of monomers passed to `Polymer` class must match "
                "number of unique entries in the specified sequence.")

        # 'A': monomer_1, 'B': monomer_2....
        seq_map = dict(zip(unique_seq_ids, self._monomers))
        last_part = None
        for n_added, seq_item in enumerate(it.cycle(sequence)):
            this_part = clone(seq_map[seq_item])
            self.add(this_part, "monomer[$]")
            if last_part is None:
                first_part = this_part
            else:
                # Transform this part, such that its bottom port is rotated
                # and translated to the last parts top port.
                force_overlap(
                    this_part,
                    this_part.labels[self._port_labels[0]],
                    last_part.labels[self._port_labels[1]],
                )
            last_part = this_part
            if n_added == n * len(sequence) - 1:
                break

        # Add the end groups
        head = self["monomer[0]"]  # First monomer
        tail = self["monomer[{}]".format(n_monomers - 1)]  # Last monomer
        if not head["up"].used:
            head_port = head["up"]
        else:
            head_port = None
        if not tail["down"].used:
            tail_port = tail["down"]
        else:
            tail_port = None

        head_tail = [head_port, tail_port]

        for i, compound in enumerate(self._end_groups):
            if compound is not None:
                if self._headtail[i] is not None:
                    head_tail[i].update_separation(self._headtail[i])
                self.add(compound)
                force_overlap(compound, compound.labels["up"], head_tail[i])
            else:
                if add_hydrogens:
                    hydrogen = H()
                    # Defaut to 1/2 H-C bond len
                    head_tail[i].update_separation(0.0547)
                    hydrogen["up"].update_separation(0.0547)
                    self.add(hydrogen)
                    force_overlap(hydrogen, hydrogen["up"], head_tail[i])
                else:
                    # if None, hoist port to polymer level
                    self.add(head_tail[i],
                             self._port_labels[i],
                             containment=False)

        for port in self.all_ports():
            if port not in self.available_ports():
                self.remove(port)
def system_builder(seed,
                   chainlength=17,
                   backbone=Alkylsilane,
                   terminal_group='methyl',
                   num_chains=100):
    """ Define system variable"""
    chainlength = chainlength
    backbone = backbone
    seed = seed
    pattern_type = "random"
    terminal_group = terminal_group
    num_chains = num_chains
    """
    -----------------------------------
    Generate amorphous silica interface
    -----------------------------------
    """
    surface_a = SilicaInterface(thickness=1.2, seed=seed)
    surface_b = SilicaInterface(thickness=1.2, seed=seed)
    """
    ------------------------------------------------------
    Generate prototype of functionalized alkylsilane chain
    ------------------------------------------------------
    """
    chain_prototype_A = backbone(chain_length=chainlength,
                                 terminal_group=terminal_group)
    chain_prototype_B = backbone(chain_length=chainlength,
                                 terminal_group=terminal_group)
    """
    ----------------------------------------------------------
    Create monolayer on surface, backfilled with hydrogen caps
    ----------------------------------------------------------
    """
    # bottom monolayer is backfilled with the other terminal group
    # num_chains = num_chains * a_fraction
    monolayer_a = SurfaceMonolayer(
        surface=surface_a,
        chains=chain_prototype_A,
        n_chains=num_chains,
        seed=seed,
        backfill=H(),
        rotate=False,
    )
    monolayer_a.name = "Bottom"
    monolayer_b = SurfaceMonolayer(
        surface=surface_b,
        chains=chain_prototype_B,
        n_chains=num_chains,
        seed=seed,
        backfill=H(),
        rotate=False,
    )
    monolayer_b.name = "Top"
    """
    ----------------------
    Create dual monolayers
    ----------------------
    """
    dual_monolayer = DualSurface(bottom=monolayer_a,
                                 top=monolayer_b,
                                 separation=2.0)
    """
    --------------------------------------------------------
    Make sure box is elongated in z to be pseudo-2D periodic
    --------------------------------------------------------
    """
    box = dual_monolayer.boundingbox
    dual_monolayer.periodicity += np.array([0, 0, 5.0 * box.lengths[2]])
    """
    -------------------------------------------------------------------
    - Save to .GRO, .TOP, and .LAMMPS formats
    - Atom-type the system using Foyer, with parameters from the OPLS
    force field obtained from GROMACS. Parameters are located in a
    Foyer XML file in  "../util/forcefield/oplsaa.xml".
    -------------------------------------------------------------------
    """

    if os.path.isfile("../util/forcefield/oplsaa.xml"):
        forcefield_filepath = "../util/forcefield/oplsaa.xml"
    elif os.path.isfile("../../../util/forcefield/oplsaa.xml"):
        forcefield_filepath = "../../../util/forcefield/oplsaa.xml"
    else:
        raise Exception('Forcefield file is not found')

    dual_monolayer.save("init.gro", residues=["Top", "Bottom"], overwrite=True)

    structure = dual_monolayer.to_parmed(box=None, residues=["Top", "Bottom"])
    ff = Forcefield(forcefield_files=forcefield_filepath)
    structure = ff.apply(structure)
    structure.combining_rule = "geometric"

    structure.save("init.top", overwrite=True)
    write_lammpsdata(filename="init.lammps", structure=structure)
    """
    --------------------------------------
    Specify index groups and write to file
    --------------------------------------
    """
    index_groups = generate_index_groups(
        system=dual_monolayer,
        terminal_group=terminal_group,
        freeze_thickness=0.5,
    )
    write_monolayer_ndx(rigid_groups=index_groups, filename="init.ndx")
    return dual_monolayer
Esempio n. 18
0
            surface.translate_to([0, 0, 0])
            surface.translate([0, 0, -1 * min(surface.xyz[:,2]) - shift])
            radius = max(surface.xyz[:,2]) - min(surface.xyz[:,2])
            pattern = RandomHemispherePattern(n=n_chains, seed=seed)
            pattern.scale(radius)
        elif surface.name == 'SilicaAsperity':
            pass
        else:
            pattern = mb.Random2DPattern(n_chains, seed=seed)
        
        if chains and n_chains > 0:
            monolayer = Monolayer(surface=surface, chains=chains, pattern=pattern,
                                  fractions=fractions, backfill=backfill, **kwargs)
        else:
            monolayer = Monolayer(surface=surface, chains=backfill, guest_port_name='up', **kwargs)

        self.add(monolayer)

if __name__ == "__main__":
    from alkylsilane import Alkylsilane
    from silica_interface import SilicaInterface
    from mbuild.lib.atoms import H

    hydrogen = H()
    seed = 12345
    chain = Alkylsilane(chain_length=6, terminal_group='methyl')

    planar_surface = SilicaInterface(seed=seed)
    planar_monolayer = SurfaceMonolayer(surface=planar_surface, 
            chains=chain, n_chains=100, seed=seed, backfill=hydrogen)
def initialize_system(job):
    """ Generate the monolayer surfaces, parametrize, save LAMMPS, GRO, TOP.
    """
    '''
    ---------------------------
    Read statepoint information
    ---------------------------
    '''
    chainlength = job.statepoint()['chainlength']
    n_chains = job.statepoint()['n']
    seed = job.statepoint()['seed']
    terminal_groups = job.statepoint()['terminal_groups']

    '''
    -----------------------------------
    Generate amorphous silica interface
    -----------------------------------
    '''
    surface_a = SilicaInterface(thickness=1.2, seed=seed)
    surface_b = SilicaInterface(thickness=1.2, seed=seed)

    '''
    ------------------------------------------------------
    Generate prototype of functionalized alkylsilane chain
    ------------------------------------------------------
    '''
    chain_prototype_a = Alkylsilane(chain_length=chainlength,
                                    terminal_group=terminal_groups[0])
    chain_prototype_b = Alkylsilane(chain_length=chainlength,
                                    terminal_group=terminal_groups[1])
    '''
    ----------------------------------------------------------
    Create monolayer on surface, backfilled with hydrogen caps
    ----------------------------------------------------------
    '''
    monolayer_a = SurfaceMonolayer(surface=surface_a, chains=chain_prototype_a,
                                   n_chains=n_chains, seed=seed,
                                   backfill=H(), rotate=False)
    monolayer_a.name = 'Bottom'
    monolayer_b = SurfaceMonolayer(surface=surface_b, chains=chain_prototype_b,
                                   n_chains=n_chains, seed=seed,
                                   backfill=H(), rotate=False)
    monolayer_b.name = 'Top'

    '''
    ------------------------------------------
    Duplicate to yield two opposing monolayers
    ------------------------------------------
    '''
    dual_monolayer = DualSurface(bottom=monolayer_a, top=monolayer_b,
                                 separation=2.0)

    '''
    --------------------------------------------------------
    Make sure box is elongated in z to be pseudo-2D periodic
    --------------------------------------------------------
    '''
    box = dual_monolayer.boundingbox
    dual_monolayer.periodicity += np.array([0, 0, 5. * box.lengths[2]])

    '''
    -------------------------------------------------------------------
    - Save to .GRO, .TOP, and .LAMMPS formats
    - Atom-type the system using Foyer, with parameters from the OPLS
    force field obtained from GROMACS. Parameters are located in a
    Foyer XML file in the `atools` git repo, with references provided
    as well as notes where parameters have been added or altered to
    reflect the literature.
    -------------------------------------------------------------------
    '''
    # path for project root dir
    proj = signac.get_project()
    forcefield_filepath = pathlib.Path(
        proj.root_directory() + "/src/util/forcefield/oplsaa.xml")
    # change into job directoryA
    _switch_dir(job)
    logging.info("at dir: {}".format(job.ws))
    dual_monolayer.save('init.gro', residues=['Top', 'Bottom'],
			    overwrite=True)

    if not (job.isfile('init.top') and job.isfile('init.lammps') and
	    job.isfile('init.gro')):

        structure = dual_monolayer.to_parmed(box=None,
					     residues=['Top', 'Bottom'])
        ff = Forcefield(forcefield_files=forcefield_filepath.as_posix())
        structure = ff.apply(structure)
        structure.combining_rule = 'geometric'

        structure.save('init.top', overwrite=True)
        write_lammpsdata(filename='init.lammps', structure=structure)

        '''
        --------------------------------------
        Specify index groups and write to file
        --------------------------------------
        '''
    index_groups = generate_index_groups(system=dual_monolayer,
					 terminal_groups=terminal_groups,
					 freeze_thickness=0.5)
    write_monolayer_ndx(rigid_groups=index_groups, filename='init.ndx')