Example #1
0
def run_nvt():

    # Use mbuild to create molecules
    methane = mbuild.load("C", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # Load forcefields
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [box]
    species_list = [methane_ff]

    # Use Cassandra to insert some initial number of species
    mols_to_add = [[50]]

    # Define the system object
    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    # Get the move probabilities
    moves = mc.Moves("nvt", species_list)

    # Run a simulation with at 300 K with 10000 MC moves
    mc.run(
        system=system,
        moves=moves,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0,
    )
def run_gcmc_restricted():

    # Use mbuild to create molecules
    methane = mbuild.load("C", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[5.0, 5.0, 5.0])

    # Load forcefields
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [box]
    species_list = [methane_ff]

    mols_to_add = [[10]]

    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    moves = mc.Moves("gcmc", species_list)

    # Specify restricted insertions
    moves.add_restricted_insertions(species_list, [["sphere"]], [[20]])

    mc.run(
        system=system,
        moves=moves,
        run_type="equilibration",
        run_length=100,
        temperature=300.0,
        chemical_potentials=[-35.0],
        prop_freq=10,
    )
Example #3
0
def run_nvt_mixture():
    # Use mbuild to create molecules
    methane = mbuild.load("C", smiles=True)
    propane = mbuild.load("CCC", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # Load forcefields
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    typed_methane = oplsaa.apply(methane)
    typed_propane = oplsaa.apply(propane)

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

    # Use Cassandra to insert some initial number of species
    mols_to_add = [[100, 50]]

    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    moves = mc.Moves("nvt", species_list)

    mc.run(
        system=system,
        moves=moves,
        run_type="equilibration",
        run_length=10000,
        temperature=200.0,
    )
Example #4
0
    def test_corrupt_natoms(self, methane_oplsaa, box):
        with pytest.raises(ValueError, match=r"corrupted"):
            system = mc.System([box], [methane_oplsaa], mols_to_add=[[10]])
            moveset = mc.MoveSet("nvt", [methane_oplsaa])

            system.mols_in_boxes[0][0] = 10
            mc.run(system, moveset, 300.0, "equilibration", 500)
Example #5
0
def run_nvt(**custom_args):

    # Use mBuild to create a methane molecule
    methane = mbuild.load("C", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # Load force field
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply force field to methane
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [box]
    species_list = [methane_ff]

    # Use Cassandra to insert some initial number of methane molecules
    mols_to_add = [[50]]

    # Define the System
    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    # Define the MoveSet
    moveset = mc.MoveSet("nvt", species_list)

    # Run a simulation at 300 K for 10000 MC moves
    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #6
0
    def test_corrupt_boxes(self, methane_oplsaa, box):
        with pytest.raises(TypeError, match=r"corrupted"):
            system = mc.System([box], [methane_oplsaa], mols_to_add=[[10]])
            moves = mc.Moves("nvt", [methane_oplsaa])

            system.boxes[0] = 1

            mc.run(system, moves, 300.0, "equilibration", 500)
Example #7
0
 def test_mismatch_boxes(self, methane_oplsaa, box):
     with pytest.raises(ValueError, match=r"requires 1 simulation"):
         system = mc.System([box, box], [methane_oplsaa],
                            mols_to_add=[[10], [0]])
         moveset = mc.MoveSet("nvt", [methane_oplsaa])
         mc.run(system, moveset, 300.0, "equilibration", 500)
     with pytest.raises(ValueError, match=r"requires 2 simulation"):
         system = mc.System([box], [methane_oplsaa], mols_to_add=[[10]])
         moveset = mc.MoveSet("gemc", [methane_oplsaa])
         mc.run(system, moveset, 300.0, "equilibration", 500)
Example #8
0
def run_gcmc_adsorption(**custom_args):

    # Use mbuild to create a zeolite supercell from CIF
    lattice = mbuild.lattice.load_cif(get_example_cif_path("TON"))
    compound_dict = {
        "Si": mbuild.Compound(name="Si"),
        "O": mbuild.Compound(name="O"),
    }
    ton = lattice.populate(compound_dict, 3, 3, 6)

    # Create a coarse-grained methane
    methane = mbuild.Compound(name="_CH4")

    # Load forcefields
    trappe_zeo = foyer.Forcefield(get_example_ff_path("trappe_zeo"))
    trappe = foyer.forcefields.load_TRAPPE_UA()

    # Use foyer to apply forcefields
    ton_ff = trappe_zeo.apply(ton)
    methane_ff = trappe.apply(methane)

    # Create box and species list
    box_list = [ton]
    species_list = [ton_ff, methane_ff]

    # Since we have an occupied box we need to specify
    # the number of each species present in the intial config
    mols_in_boxes = [[1, 0]]

    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moveset = mc.MoveSet("gcmc", species_list)

    default_args = {
        "chemical_potentials": ["none", -30.0 * (u.kJ / u.mol)],
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 14.0 * u.angstrom,
        "charge_cutoff": 14.0 * u.angstrom,
        "coord_freq": 100,
        "prop_freq": 10,
    }

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

    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #9
0
def run_cassandra_surf(chem_pot, temp):
    # Create box and species list
    box_list = [surface]
    species_list = [typed_surface,typed_ethane]

    # Since we have an occupied box we need to specify
    # the number of each species present in the intial config
    mols_in_boxes = [[2,0]]

    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moveset = mc.MoveSet("gcmc", species_list)

    custom_args = {
        "run_name": f"surfequil_{chem_pot:.0f}_{temp:.0f}",
        "chemical_potentials": ["none",chem_pot*u.Unit('kJ/mol')],
        "rcut_min": 0.3980 * 2.5* u.angstrom, #(or 3.0)
        "vdw_cutoff": min(box.lengths)/2.1* u.angstrom,
        "charge_style": "none",
        #"charge_cutoff": 14.0,
        "coord_freq": 100,
        "prop_freq": 10,
    }

    mc.run(
        system=system, 
        moveset=moveset, 
        run_type="equilibration", 
        run_length= 3600549, # To reach ~1.33 hours
        temperature=temp*u.K, 
        **custom_args
    )
    
    # Set max translate and volume for production
    moveset.max_translate = [[0* u.angstrom,10.0* u.angstrom]] # angstroms

    # Update run_name and restart_name
    custom_args["run_name"] = f"surfprod_{chem_pot:.0f}_{temp:.0f}"
    custom_args["restart_name"] = f"surfequil_{chem_pot:.0f}_{temp:.0f}"

    mc.restart(
        system=system,
        moveset=moveset,
        run_type="production",
        run_length= 24097256, # To reach ~6.67 hours, total 8 hrs
        temperature=temp*u.K,
        **custom_args,
    )
Example #10
0
def run_nvt_spce(**custom_args):
    # If no custom args are passed, assign empty dictionary
    #if custom_args is None:
    #    custom_args = {}

    # Load water with SPC/E geometry from mol2 file
    molecule = mbuild.load(get_example_mol2_path("spce"))

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # Load forcefields
    spce = foyer.Forcefield(get_example_ff_path("spce"))

    # Use foyer to apply forcefields
    molecule_ff = spce.apply(molecule)

    # Create box and species list
    box_list = [box]
    species_list = [molecule_ff]

    # Use Cassandra to insert some initial number of species
    mols_to_add = [[50]]

    # Define the system object
    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    # Get the move probabilities
    moveset = mc.MoveSet("nvt", species_list)

    default_args = {
        "angle_style": ["fixed"],
    }

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

    # Run a simulation with at 300 K with 10000 MC moveset
    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #11
0
def run_gcmc_adsorption(**custom_args):

    # Use mbuild to create molecules
    lattice = carbon_lattice()
    methane = mbuild.load("C", smiles=True)

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

    # Use foyer to apply forcefields
    typed_lattice = trappe.apply(lattice)
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [lattice]
    species_list = [typed_lattice, methane_ff]

    # Since we have an occupied box we need to specify
    # the number of each species present in the intial config
    mols_in_boxes = [[1, 0]]

    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moveset = mc.MoveSet("gcmc", species_list)

    default_args = {
        "chemical_potentials": ["none", -30.0 * (u.kJ / u.mol)],
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 14.0 * u.angstrom,
        "charge_cutoff": 14.0 * u.angstrom,
        "coord_freq": 100,
        "prop_freq": 10,
    }

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

    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #12
0
def run_gcmc_restricted(**custom_args):

    # Use mbuild to create molecules
    methane = mbuild.load("C", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[5.0, 5.0, 5.0])

    # Load forcefields
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [box]
    species_list = [methane_ff]

    mols_to_add = [[10]]

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

    # Specify restricted insertions
    moveset.add_restricted_insertions(
        species_list, [["sphere"]], [[20 * u.angstrom]]
    )

    default_args = {
        "chemical_potentials": [-35.0 * (u.kJ / u.mol)],
        "prop_freq": 10,
    }

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

    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=100,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #13
0
def run_nvt_mbuild(fix_bonds, **custom_args):

    dme = mbuild.load("COC", smiles=True)
    dee = mbuild.load("CCOCC", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # fill box
    box = mbuild.fill_box([dme, dee], n_compounds=[10, 10], box=box)

    # Load forcefields
    ff = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    dme_ff = ff.apply(dme)
    dee_ff = ff.apply(dee)

    # Create box and species list
    box_list = [box]
    species_list = [dme_ff, dee_ff]

    # Use Cassandra to insert some initial number of species
    mols_in_boxes = [[10, 10]]

    # Define the system object
    system = mc.System(
        box_list,
        species_list,
        mols_in_boxes=mols_in_boxes,
        fix_bonds=fix_bonds,
    )
    # Get the move probabilities
    moveset = mc.MoveSet("nvt", species_list)

    # Run a simulation with at 300 K with 10000 MC moves
    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=100,
        temperature=300.0 * u.K,
        **custom_args,
    )
Example #14
0
def run_npt(**custom_args):

    # Use mbuild to create molecules
    methane = mbuild.load("C", smiles=True)

    # Create an empty mbuild.Box
    box = mbuild.Box(lengths=[3.0, 3.0, 3.0])

    # Load forcefields
    oplsaa = foyer.forcefields.load_OPLSAA()

    # Use foyer to apply forcefields
    methane_ff = oplsaa.apply(methane)

    # Create box and species list
    box_list = [box]
    species_list = [methane_ff]

    # Use Cassandra to insert some initial number of species
    mols_to_add = [[5]]

    # Define the system object
    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)
    # Get the move probabilities
    moveset = mc.MoveSet("npt", species_list)

    default_args = {
        "pressure": 1.0 * u.bar,
    }

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

    # Run a simulation with at 300 K with 10000 MC moveset
    # Note we must define a pressure for an NPT simulation
    mc.run(
        system=system,
        moveset=moveset,
        run_type="equilibration",
        run_length=10000,
        temperature=300.0 * u.K,
        **custom_args,
    )
def run_adsorption(
    empty_pore,
    pore_width,
    temperature,
    mu,
    nsteps,
    **custom_args,
):
    """Run adsorption simulation at the specified temperature
    and chemical potential

    Parameters
    ----------
    empty_pore : porebuilder.GraphenePore
        empty pore system to simulate
    pore_width : u.unyt_quantity (length)
        width of pore for restricted insertions
    temperature: u.unyt_quantity (temperature)
        desired temperature
    mu : u.unyt_quantity (energy)
        desired chemical potential
    nsteps : int
        number of MC steps in simulation
    custom_args : opt, additional keyword arguments
        provide additional custom keyword arguments to MoSDeF Cassandra
        and override the default values

    Returns
    -------
    None: runs simulation
    """

    # Load foyer ff
    ff = foyer.Forcefield(get_ff("pore-spce.xml"))

    # Apply ff
    typed_pore = ff.apply(empty_pore)

    # Create a water molecule with the spce geometry
    typed_water = ff.apply(spce_water)

    # Create box and species list
    box_list = [empty_pore]
    species_list = [typed_pore, typed_water]

    # Specify mols at start of the simulation
    mols_in_boxes = [[1, 0]]

    # Create MC system
    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moves = mc.MoveSet("gcmc", species_list)

    # Set move probabilities
    moves.prob_translate = 0.25
    moves.prob_rotate = 0.25
    moves.prob_insert = 0.25
    moves.prob_regrow = 0.0

    # Specify the restricted insertion
    restricted_type = [[None, "slitpore"]]
    restricted_value = [[None, 0.5 * pore_width]]
    moves.add_restricted_insertions(species_list, restricted_type,
                                    restricted_value)

    # Set thermodynamic properties
    thermo_props = [
        "energy_total",
        "energy_intervdw",
        "energy_interq",
        "nmols",
    ]

    default_args = {
        "run_name": "gcmc",
        "cutoff_style": "cut",
        "charge_style": "ewald",
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 9.0 * u.angstrom,
        "charge_cutoff": 9.0 * u.angstrom,
        "properties": thermo_props,
        "angle_style": ["harmonic", "fixed"],
        "coord_freq": 100000,
        "prop_freq": 1000,
    }

    custom_args = {**default_args, **custom_args}

    mc.run(
        system=system,
        moveset=moves,
        run_type="equilibration",
        run_length=nsteps,
        temperature=temperature,
        chemical_potentials=["none", mu],
        **custom_args,
    )
Example #16
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,
    )

    mc.restart(
        restart_from="equil",
        run_name="prod",
        run_type="production",
        total_run_length=750,
    )
def run_nvt(filled_pore, temperature, nsteps_eq, nsteps_prod, **custom_args):
    """Run an NVT MC simulation at the specified temperature

    Parameters
    ----------
    filled_pore : porebuilder.GraphenePoreSolvent
        pore filled with water
    temperature: u.unyt_quantity (temperature)
        desired temperature
    nsteps_eq : int
        number of MC steps for NVT equilibration
    nsteps_prod : int
        number of MC steps for GCMC simulation
    custom_args : opt, additional keyword arguments
        provide additional custom keyword arguments to MoSDeF Cassandra
        and override the default values

    Returns
    -------
    None: runs simulation
    """

    # Load foyer ff
    ff = foyer.Forcefield(get_ff("pore-spce.xml"))

    # Extract just the pore and apply ff
    empty_pore = filled_pore.children[0]
    typed_pore = ff.apply(empty_pore)

    # Create a water molecule with the spce geometry and apply ff
    typed_water = ff.apply(spce_water)

    # Determine the number of waters in the pore
    nwater = len([child for child in filled_pore.children]) - 1

    # Create box and species list
    box_list = [filled_pore]
    species_list = [typed_pore, typed_water]

    # Specify mols at start of the simulation
    mols_in_boxes = [[1, nwater]]

    # Create MC system
    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moves = mc.MoveSet("nvt", species_list)

    # Set move probabilities
    moves.prob_translate = 0.5
    moves.prob_rotate = 0.5
    moves.prob_regrow = 0.0

    # Set thermodynamic properties
    thermo_props = [
        "energy_total",
        "energy_intervdw",
        "energy_interq",
    ]

    default_args = {
        "run_name": "equil.nvt",
        "cutoff_style": "cut",
        "charge_style": "ewald",
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 9.0 * u.angstrom,
        "charge_cutoff": 9.0 * u.angstrom,
        "properties": thermo_props,
        "angle_style": ["harmonic", "fixed"],
        "coord_freq": 10000,
        "prop_freq": 1000,
    }

    custom_args = {**default_args, **custom_args}

    # Run NVT equilibration
    mc.run(
        system=system,
        moveset=moves,
        run_type="equilibration",
        run_length=nsteps_eq,
        temperature=temperature,
        **custom_args,
    )

    # Run production
    custom_args["run_name"] = "prod.nvt"
    custom_args["restart_name"] = "equil.nvt"
    mc.restart(
        system=system,
        moveset=moves,
        run_type="production",
        run_length=nsteps_prod,
        temperature=temperature,
        **custom_args,
    )
Example #18
0
def main():

    # Load TON from a CIF file, replicate the cell
    # Use mbuild to create a zeolite supercell from CIF
    cif_path = resource_filename(
        "mc_examples",
        "realistic_workflows/zeolite_adsorption/resources/structures/TON.cif")
    lattice = mbuild.lattice.load_cif(cif_path)
    compound_dict = {
        "Si": mbuild.Compound(name="Si"),
        "O": mbuild.Compound(name="O"),
    }
    zeolite = lattice.populate(compound_dict, 2, 2, 6)

    # 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 pure fluid temperatures and chemical potentials
    temperatures = [298 * u.K, 309 * u.K, 350 * u.K]
    mus_fluid = np.arange(-49, -30, 3) * u.Unit("kJ/mol")

    # Define the pressures at which we wish to study adsorption
    pressures = [
        0.01,
        0.1,
        0.25,
        0.5,
        0.75,
        1.0,
        2.0,
        3.0,
        5.0,
    ] * u.bar

    # Select the zeolite ff
    zeo_ff_names = ["june", "trappe"]

    # Define a few custom_args that will be
    # the same for all zeolite simulations
    custom_args = {
        "charge_style": "none",
        "vdw_cutoff": 14.0 * u.angstrom,
        "prop_freq": 10,
        "max_molecules": [1, 10000],
    }

    # Loop over different zeolite ff's
    for zeo_ff_name in zeo_ff_names:

        # Load and apply ff to the zeolite structure
        ff_path = resource_filename(
            "mc_examples",
            f"realistic_workflows/zeolite_adsorption/resources/ffxml/zeo_{zeo_ff_name}.xml",
        )
        ff_zeo = foyer.Forcefield(ff_path)
        zeolite_ff = ff_zeo.apply(zeolite)

        # Create the box_list, species_list, System, and MoveSet.
        # These are not dependent upon (T,P) condition
        box_list = [zeolite]
        species_list = [zeolite_ff, methane_ff]
        mols_in_boxes = [[1, 0]]

        system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
        moveset = mc.MoveSet("gcmc", species_list)

        # Loop over each temperature to compute an isotherm
        for temperature in temperatures:

            # Before we begin we must determine the
            # chemical potentials required to achieve
            # the desired pressures
            fluid_pressures = []
            for mu_fluid in mus_fluid:
                dirname = f"fluid_T_{temperature:0.1f}_mu_{mu_fluid:.1f}".replace(
                    " ", "_").replace("/", "-")
                thermo = ThermoProps(dirname + "/prod.out.prp")
                fluid_pressures.append(np.mean(thermo.prop("Pressure")))
            fluid_pressures = u.unyt_array(fluid_pressures)

            # Fit a line to mu vs. P
            slope, intercept, r_value, p_value, stderr = linregress(
                np.log(fluid_pressures.to_value(u.bar)).flatten(),
                y=mus_fluid.to_value("kJ/mol").flatten(),
            )
            # Determine chemical potentials
            mus = (slope * np.log(pressures.in_units(u.bar)) +
                   intercept) * u.Unit("kJ/mol")

            # Loop over each pressure and run the MC simulation!
            for (pressure, mu) in zip(pressures, mus):
                print(f"\nRun simulation: T = {temperature}, P = {pressure}\n")
                dirname = f"zeo_ff_{zeo_ff_name}_T_{temperature:0.1f}_P_{pressure:0.2f}".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=["none", mu],
                        **custom_args,
                    )

                    mc.restart(
                        restart_from="equil",
                        run_name="prod",
                        run_type="prod",
                        total_run_length=200000,
                    )
Example #19
0
def main():
    # Create a water molecule with the spce geometry
    water = spce_water
    ff = foyer.Forcefield(get_ff("pore-spce-jc.xml"))
    water_typed = ff.apply(water)

    # Define conditions
    temperature = 298.0 * u.K
    # Define a range of (shifted) chemical potentials
    mus_adsorbate = np.arange(-58, -42, 2) * u.Unit("kJ/mol")

    # Define custom_args that are the same for all pure phase simulations
    custom_args = {
        "cutoff_style": "cut",
        "charge_style": "ewald",
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 9.0 * u.angstrom,
        "prop_freq": 10,
        "angle_style": ["fixed"],
    }

    for mu_adsorbate in mus_adsorbate:
        print(f"\nRun simulation: T = {temperature}, mu = {mu_adsorbate}\n")
        dirname = f"T_{temperature:0.1f}_mu_{mu_adsorbate:.1f}".replace(
            " ", "_"
        ).replace(
            "/", "-"
        )
        if not os.path.isdir(dirname):
            os.mkdir(dirname)
        else:
            pass
        with temporary_cd(dirname):
            # Box size depends on chemical potential
            # Test simulations show mu' = -48 kJ/mol; p ~ 0.01 bar
            # Employ IG law to estimate remaining box sizes; target 40 waters
            mu_0 = -48 * u.kJ/u.mol
            p_0 = 0.01 * u.bar
            n_water_target = 40
            p_ig = p_0 * np.exp((mu_adsorbate-mu_0)/(u.kb * temperature))
            vol = n_water_target * u.kb * temperature / p_ig
            boxl = (vol**(1./3.)).to_value("nm")
            custom_args["charge_cutoff"] = 0.25 * boxl * u.nm

            species_list = [water_typed]
            box_list = [mbuild.Box([boxl, boxl, boxl])]
            system = mc.System(
                box_list, species_list,
            )
            moveset = mc.MoveSet("gcmc", species_list)
            moveset.prob_regrow = 0.0
            moveset.prob_translate = 0.3
            moveset.prob_rotate = 0.3
            moveset.prob_insert = 0.2

            mc.run(
                system=system,
                moveset=moveset,
                run_type="equil",
                run_length=500000,
                temperature=temperature,
                run_name="equil",
                chemical_potentials=[mu_adsorbate],
                **custom_args,
            )

            mc.restart(
                system=system,
                moveset=moveset,
                run_type="prod",
                run_length=1000000,
                temperature=temperature,
                run_name="prod",
                restart_name="equil",
                chemical_potentials=[mu_adsorbate],
                **custom_args,
            )
Example #20
0
def equilibrate_liqbox(job):
    "Equilibrate the liquid box"

    import os
    import errno
    import mbuild
    import foyer
    import mosdef_cassandra as mc

    ff = foyer.Forcefield(job.fn("ff.xml"))

    # Load the compound and apply the ff
    compound = mbuild.load("C(F)(F)C(F)(F)F", smiles=True)
    compound_ff = ff.apply(compound)

    # Create box list and species list
    boxl = job.doc.liqboxl
    box = mbuild.Box(lengths=[boxl, boxl, boxl])

    box_list = [box]
    species_list = [compound_ff]

    mols_to_add = [[job.sp.N_liq]]

    system = mc.System(box_list, species_list, mols_to_add=mols_to_add)

    # Create a new moves object
    moves = mc.Moves("npt", species_list)

    # Edit the volume move probability to be more reasonable
    orig_prob_volume = moves.prob_volume
    new_prob_volume = 1.0 / job.sp.N_liq
    moves.prob_volume = new_prob_volume

    moves.prob_translate = (moves.prob_translate + orig_prob_volume -
                            new_prob_volume)

    # Define thermo output props
    thermo_props = [
        "energy_total",
        "pressure",
        "volume",
        "nmols",
        "mass_density",
    ]

    # Define custom args
    custom_args = {
        "run_name": "equil",
        "charge_style": "ewald",
        "rcut_min": 1.0,
        "vdw_cutoff": 12.0,
        "units": "sweeps",
        "steps_per_sweep": job.sp.N_liq,
        "coord_freq": 500,
        "prop_freq": 10,
        "properties": thermo_props,
    }

    # Move into the job dir and start doing things
    with job:
        liq_dir = "liqbox-equil"
        try:
            os.mkdir(liq_dir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise
        os.chdir(liq_dir)
        # Run equilibration
        mc.run(system=system,
               moves=moves,
               run_type="equilibration",
               run_length=job.sp.nsteps_liqeq,
               temperature=job.sp.T,
               pressure=job.sp.P,
               **custom_args)
Example #21
0
def run_gemc():

    # 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)
    moves = mc.Moves("gemc", species_list)

    moves.prob_volume = 0.010
    moves.prob_swap = 0.11

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

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

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

    # Set max translate and volume for production
    moves.max_translate = [[0.5], [14.0]]
    moves.max_volume = [700.0]

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

    mc.restart(
        system=system,
        moves=moves,
        run_type="production",
        run_length=750,
        temperature=151.0,
        **custom_args,
    )
Example #22
0
box = mbuild.Box([box_length, box_length, box_length])
vapor_box = mbuild.fill_box(ethane, n_compounds=N_vapor, box=box)

# Initial liquid box from existing configuration
liquid_box = mbuild.load("liqbox_equil.gro")
N_liquid = len([child for child in liquid_box.children])

# Create the System and MoveSet
box_list = [liquid_box, vapor_box]
species_list = [ethane_ff]
mols_in_boxes = [[N_liquid], [N_vapor]]

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

# Run the Monte Carlo simulation
mc.run(
    system=system,
    moveset=moveset,
    run_type="equilibration",
    run_length=500000,
    temperature=temperature,
    vdw_cutoff=10.0 * u.angstrom,
    charge_cutoff=10.0 * u.angstrom,
    mixing_rule="geometric",
)
Example #23
0
def run_gcmc(
        filled_pore,
        pore_width,
        temperature,
        mu,
        nsteps_nvt,
        nsteps_gcmc,
        pve_ion=mbuild.Compound(name="Na"),
        nve_ion=mbuild.Compound(name="Cl"),
        **custom_args,
):
    """Run desorption simulation at the specified temperature
    and chemical potential
    Parameters
    ----------
    filled_pore : porebuilder.GraphenePoreSolvent
        pore filled with water and (optional) ions
    pore_width : u.unyt_quantity (length)
        width of pore for restricted insertions
    temperature: u.unyt_quantity (temperature)
        desired temperature
    mu : u.unyt_quantity (energy)
        desired chemical potential for water
    nsteps_nvt : int
        number of MC steps for NVT equilibration
    nsteps_gcmc : int
        number of MC steps for GCMC simulation
    pve_ion : mbuild.Compound, optional, default=Na
        positive ion
    nve_ion : mbuild.Compound, optional, default=Cl
        negative ion
    custom_args : opt, additional keyword arguments
        provide additional custom keyword arguments to MoSDeF Cassandra
        and override the default values
    Returns
    -------
    None: runs simulation
    """

    # Load foyer ff
    ff = foyer.Forcefield(get_ff("pore-spce-jc.xml"))

    # Extract just the pore and apply ff
    empty_pore = filled_pore.children[0]
    typed_pore = ff.apply(empty_pore)

    # Create a water molecule with the spce geometry and apply ff
    typed_water = ff.apply(spce_water)
    typed_pve = ff.apply(pve_ion)
    typed_nve = ff.apply(nve_ion)

    # Determine the number of waters in the pore
    n_water = len(
        [child for child in filled_pore.children if child.name == "SOL"])
    n_ion_pairs = int(
        (len([child for child in filled_pore.children]) - 1 - n_water) / 2)

    # Create box and species list
    box_list = [filled_pore]
    species_list = [typed_pore, typed_pve, typed_nve, typed_water]

    # Specify mols at start of the simulation
    mols_in_boxes = [[1, n_ion_pairs, n_ion_pairs, n_water]]

    # Create MC system
    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moves = mc.MoveSet("nvt", species_list)

    # Set move probabilities
    moves.prob_translate = 0.5
    moves.prob_rotate = 0.5
    moves.prob_regrow = 0.0

    # Set thermodynamic properties
    thermo_props = [
        "energy_total",
        "energy_intervdw",
        "energy_interq",
        "nmols",
    ]

    default_args = {
        "run_name": "nvt",
        "cutoff_style": "cut",
        "charge_style": "ewald",
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 9.0 * u.angstrom,
        "charge_cutoff": 9.0 * u.angstrom,
        "properties": thermo_props,
        "angle_style": ["harmonic", "harmonic", "harmonic", "fixed"],
        "coord_freq": 100000,
        "prop_freq": 1000,
    }

    custom_args = {**default_args, **custom_args}

    # Run NVT equilibration
    mc.run(
        system=system,
        moveset=moves,
        run_type="equilibration",
        run_length=nsteps_nvt,
        temperature=temperature,
        **custom_args,
    )

    # Create MC system
    equilibrated_box = load_final_xyz_frame("nvt.out.xyz")
    box_list = [equilibrated_box]
    system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes)
    moves = mc.MoveSet("gcmc", species_list)

    # Set move probabilities
    moves.prob_translate = 0.25
    moves.prob_rotate = 0.25
    moves.prob_insert = 0.25
    moves.prob_regrow = 0.0

    # Make Na/Cl NOT insertable
    moves.insertable[1] = False
    moves.insertable[2] = False

    # Specify the restricted insertion
    restricted_type = [[None, None, None, "slitpore"]]
    restricted_value = [[None, None, None, 0.5 * pore_width]]
    moves.add_restricted_insertions(species_list, restricted_type,
                                    restricted_value)

    # Run GCMC
    custom_args["run_name"] = "gcmc"
    mc.run(
        system=system,
        moveset=moves,
        run_type="equilibration",
        run_length=nsteps_gcmc,
        temperature=temperature,
        chemical_potentials=["none", "none", "none", mu],
        **custom_args,
    )
Example #24
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,
                )
Example #25
0
# 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,
    moveset=moveset,
    run_type="equilibration",
    run_length=300000,
    temperature=240 * u.K,
    pressure=10.0 * u.bar,
    vdw_cutoff=14.0 * u.angstrom,
)
Example #26
0
# 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,
    moveset=moveset,
    run_type="equilibration",
    run_length=300000,
    temperature=240 * u.K,
    pressure=10.0 * u.bar,
)
Example #27
0
def run_gemc(job):
    "Run gemc"

    import mbuild
    import foyer
    import mosdef_cassandra as mc

    ff = foyer.Forcefield(job.fn("ff.xml"))

    # Load the compound and apply the ff
    compound = mbuild.load("C(F)(F)C(F)(F)F", smiles=True)
    compound_ff = ff.apply(compound)

    # Create box list and species list
    boxl = job.doc.liqbox_final_dim  # saved in nm
    liq_box = mbuild.load(job.fn("liqbox.xyz"))
    liq_box.periodicity = [boxl, boxl, boxl]
    boxl = job.doc.vapboxl  # nm
    vap_box = mbuild.Box(lengths=[boxl, boxl, boxl])

    box_list = [liq_box, vap_box]
    species_list = [compound_ff]

    mols_in_boxes = [[job.sp.N_liq], [0]]
    mols_to_add = [[0], [job.sp.N_vap]]

    system = mc.System(
        box_list,
        species_list,
        mols_in_boxes=mols_in_boxes,
        mols_to_add=mols_to_add,
    )

    # Create a new moves object
    moves = mc.Moves("gemc", species_list)

    # Edit the volume and swap move probability to be more reasonable
    orig_prob_volume = moves.prob_volume
    orig_prob_swap = moves.prob_swap
    new_prob_volume = 1.0 / (job.sp.N_liq + job.sp.N_vap)
    new_prob_swap = 4.0 / 0.05 / (job.sp.N_liq + job.sp.N_vap)
    moves.prob_volume = new_prob_volume
    moves.prob_swap = new_prob_swap

    moves.prob_translate = (moves.prob_translate + orig_prob_volume -
                            new_prob_volume)
    moves.prob_translate = (moves.prob_translate + orig_prob_swap -
                            new_prob_swap)

    # Define thermo output props
    thermo_props = [
        "energy_total",
        "pressure",
        "volume",
        "nmols",
        "mass_density",
        "enthalpy",
    ]

    # Define custom args
    custom_args = {
        "run_name": "equil",
        "charge_style": "ewald",
        "rcut_min": 1.0,
        "charge_cutoff_box2": 25.0,
        "vdw_cutoff_box1": 12.0,
        "vdw_cutoff_box2": 25.0,
        "units": "sweeps",
        "steps_per_sweep": job.sp.N_liq + job.sp.N_vap,
        "coord_freq": 500,
        "prop_freq": 10,
        "properties": thermo_props,
    }

    # Move into the job dir and start doing things
    with job:
        # Run equilibration
        mc.run(system=system,
               moves=moves,
               run_type="equilibration",
               run_length=job.sp.nsteps_eq,
               temperature=job.sp.T,
               **custom_args)

        # Adjust custom args for production
        custom_args["run_name"] = "prod"
        custom_args["restart_name"] = "equil"

        # Run production
        mc.restart(system=system,
                   moves=moves,
                   run_type="production",
                   run_length=job.sp.nsteps_prod,
                   temperature=job.sp.T,
                   **custom_args)
Example #28
0
def run_simulation(job):
    """Run GCMC simulations for the given statepoint"""

    import mbuild
    import foyer
    import unyt as u
    import numpy as np
    import mosdef_cassandra as mc

    from mosdef_slitpore.utils.cassandra_helpers import spce_water
    from mosdef_slitpore.utils.utils import get_ff

    temperature = job.sp.T * u.K
    mu = job.sp.mu * u.kJ / u.mol
    nsteps_eq = job.sp.nsteps.equil
    nsteps_prod = job.sp.nsteps.prod
    seed1 = job.sp.seed1
    seed2 = job.sp.seed2

    # Want box size to depend on chemical potential
    # Prelim simulation shows mu' = -48 kJ/mol; p ~ 0.01 bar
    # Employ IG law to estimate remaining box sizes; target 40 waters
    mu_0 = -48 * u.kJ / u.mol
    p_0 = 0.01 * u.bar
    n_water_target = 40
    p_ig = p_0 * np.exp((mu - mu_0) / (u.kb * temperature))
    vol = n_water_target * u.kb * temperature / p_ig
    boxl = (vol**(1. / 3.)).to_value("nm")

    # Define custom_args that are the same
    # for all pure phase simulations
    custom_args = {
        "cutoff_style": "cut",
        "charge_style": "ewald",
        "rcut_min": 0.5 * u.angstrom,
        "vdw_cutoff": 9.0 * u.angstrom,
        "charge_cutoff": 0.25 * boxl * u.nm,
        "prop_freq": 1000,
        "angle_style": ["fixed"],
        "seeds": [seed1, seed2],
    }

    # Create a water molecule with the spce geometry
    ff = foyer.Forcefield(get_ff("pore-spce.xml"))
    water_typed = ff.apply(spce_water)

    species_list = [water_typed]
    box_list = [mbuild.Box([boxl, boxl, boxl])]
    system = mc.System(
        box_list,
        species_list,
    )
    moveset = mc.MoveSet("gcmc", species_list)
    moveset.prob_regrow = 0.0
    moveset.prob_translate = 0.3
    moveset.prob_rotate = 0.3
    moveset.prob_insert = 0.2

    with job:
        mc.run(
            system=system,
            moveset=moveset,
            run_type="equil",
            run_length=nsteps_eq,
            temperature=temperature,
            run_name="equil",
            chemical_potentials=[mu],
            **custom_args,
        )

        mc.restart(
            system=system,
            moveset=moveset,
            run_type="prod",
            run_length=nsteps_prod,
            temperature=temperature,
            run_name="prod",
            restart_name="equil",
            chemical_potentials=[mu],
            **custom_args,
        )