Beispiel #1
0
def main():

    # Systems simulated
    pore_area = 2 * 22.104 * 21.270 * u.angstrom**2  # From .inp file
    pore_sizes = [1.0, 1.5, 2.0] * u.nm
    n_ion_pairs = [0, 4, 8]

    # Output
    nmols_list = []
    pore_sizes_list = []
    n_ion_pair_list = []

    for pore_size in pore_sizes:
        for n_ion_pair in n_ion_pairs:
            thermo_path = f"../gcmc_pore/{pore_size.to_value('nm')}nm_{n_ion_pair}pairs/gcmc.out.prp"
            thermo = ThermoProps(thermo_path)
            nmols_list.append(thermo.prop("Nmols_4", start=20000000).mean())
            pore_sizes_list.append(pore_size)
            n_ion_pair_list.append(n_ion_pair)

    df = pd.DataFrame(
        columns=["pore_size_nm", "n_ion_pairs", "nmols", "nmols_per_nm^2"])
    df["pore_size_nm"] = np.array(pore_sizes_list)
    df["n_ion_pairs"] = np.array(n_ion_pair_list)
    df["nmols"] = np.array(nmols_list)
    df["nmols_per_nm^2"] = np.array(nmols_list) / pore_area.to_value(u.nm**2)
    df.to_csv("results_gcmc_pore.csv")
Beispiel #2
0
def main():

    pore_area = 2 * 29.472 * 29.777 * u.angstrom**2

    project = signac.get_project("../")
    mus = []
    nmols = []
    runs = []
    for job in project:
        runs.append(job.sp.run)
        mus.append(job.sp.mu * u.kJ/u.mol)
        thermo = ThermoProps(job.fn("gcmc.out.prp"))
        nmols.append(thermo.prop("Nmols_2", start=200000000).mean())

    mus = u.unyt_array(mus * u.kJ/u.mol)
    nmols = np.asarray(nmols)
    runs = np.asarray(runs)
    df = pd.DataFrame(
        columns=["mu-cassandra_kJmol", "run", "nmols_per_nm^2"]
    )
    df["mu-cassandra_kJmol"] = mus.to_value("kJ/mol")
    df["run"] = runs
    df["nmols"] = nmols
    df["nmols_per_nm^2"] = nmols / pore_area.to_value(u.nm**2)
    df.to_csv("results.csv")
Beispiel #3
0
    def test_to_df(self):
        thermo = ThermoProps(get_fn("equil.out.box1.prp"))
        df = thermo.to_df()
        arrays = [
            (
                "MC_SWEEP",
                "Energy_Total",
                "Energy_InterVDW",
                "Pressure",
                "Volume",
                "Nmols",
                "Mass_Density",
            ),
            (
                "",
                "(kJ/mol)-Ext",
                "(kJ/mol)-Ext",
                "(bar)",
                "(A^3)",
                "",
                "(kg/m^3)",
            ),
        ]

        multi_index = pd.MultiIndex.from_arrays(
            arrays, names=("property", "units")
        )
        assert (df.columns == multi_index).all()
        assert df.shape == (201, 7)
Beispiel #4
0
def main():

    # Input conditions
    temperature = 298.0 * u.K
    mus = np.arange(-58, -42, 2) * u.Unit("kJ/mol")

    # Output
    pressures = []

    for mu in mus:
        dirname = f"T_{temperature:0.1f}_mu_{mu:.1f}".replace(
            " ", "_"
        ).replace(
            "/", "-"
        )
        thermo_path = "../gcmc_bulk/" + dirname + "/prod.out.prp"
        thermo = ThermoProps(thermo_path)
        pressures.append(thermo.prop("Pressure").mean())

    pressures = u.unyt_array(pressures)

    df = pd.DataFrame(
        columns=["mu-cassandra_kJmol", "pressure_bar"]
    )
    df["mu-cassandra_kJmol"] = mus.to_value("kJ/mol")
    df["pressure_bar"] = pressures.to_value("bar")
    df.to_csv("results_gcmc_bulk.csv")
Beispiel #5
0
    def test_extract_range(self):
        thermo = ThermoProps(get_fn("equil.out.box1.prp"))
        pressure = thermo.prop("Pressure", start=15, end=30)
        sweep = thermo.prop("MC_SWEEP", start=15, end=30)

        assert pressure.shape == sweep.shape == (4,)
        assert np.isclose(sweep[0].value, 15)
        assert np.isclose(sweep[-1].value, 30)
        assert np.isclose(pressure[0].value, 152.82276)
        assert np.isclose(pressure[-1].value, -2.9842435)
Beispiel #6
0
def main():

    # Define conditions
    temperature = 298.0 * u.K

    project = signac.get_project("../")

    mus = []
    pressures = []

    for job in project:
        mus.append(job.sp.mu * u.kJ / u.mol)
        thermo = ThermoProps(job.fn("prod.out.prp"))
        pressures.append(thermo.prop("Pressure").mean())

    mus = u.unyt_array(mus)
    pressures = u.unyt_array(pressures)

    df = pd.DataFrame(columns=["mu-cassandra_kJmol", "pressure_bar"])
    df["mu-cassandra_kJmol"] = mus.to_value("kJ/mol")
    df["pressure_bar"] = pressures.to_value("bar")
    df.to_csv("results.csv")
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,
                    )
def main():

    # Make sure the range of temperatures and pressures
    # matches those for which the simulations were run
    zeo_ff_names = ["june", "trappe"]
    temperatures = [298.0 * u.K, 309.0 * u.K, 350 * u.K]
    pressures = [
        0.01,
        0.1,
        0.25,
        0.5,
        0.75,
        1.0,
        2.0,
        3.0,
        5.0,
    ] * u.bar

    # Define the number of unit cells (2x2x6=24)
    n_unitcells = 24

    # Create a location to output our results
    outdir = "plots/"
    if not os.path.isdir(outdir):
        os.mkdir(outdir)
    else:
        pass

    # First let's check the equilibration length. We'll plot
    # the number of molecules/unitcell over the simulations
    for zeo_ff_name in zeo_ff_names:
        property_ = "Nmols_2"
        for temperature in temperatures:
            fig, ax = plt.subplots()
            for pressure in pressures:
                dirname = f"zeo_ff_{zeo_ff_name}_T_{temperature:0.1f}_P_{pressure:0.2f}".replace(
                    " ", "_").replace("/", "-")
                thermo_equil = ThermoProps(dirname + "/equil.out.prp")
                thermo_prod = ThermoProps(dirname + "/prod.out.prp")
                ax.plot(
                    np.hstack((thermo_equil.prop("MC_STEP"),
                               thermo_prod.prop("MC_STEP"))),
                    np.hstack((thermo_equil.prop(property_),
                               thermo_prod.prop(property_))) / n_unitcells,
                    label=pressure,
                )
            ax.set_title("$\mathregular{N_{methane}}$" +
                         f", T = {temperature}",
                         fontsize=16)
            ax.set_xlabel("MC Step", fontsize=16)
            ax.set_ylabel("$\mathregular{N_{methane}}$/unit cell", fontsize=16)
            ax.tick_params(which="both",
                           direction="in",
                           labelsize=14,
                           top=True,
                           right=True)
            fig.legend()
            fig.tight_layout(pad=2)
            fig.savefig(
                outdir +
                f"/Nmols_zeo_ff_{zeo_ff_name}_T{temperature.value}K.pdf")

    # Next let's calculate the average number of molecules per unit
    # cell during the production simulation and plot the isotherms
    fig, ax = plt.subplots()

    # Load lit results to compare
    file_path = resource_filename(
        "mc_examples",
        "realistic_workflows/zeolite_adsorption/resources/lit_results/tjune_TON-methane_298K.txt",
    )
    lit_298K = np.genfromtxt(file_path, skip_header=1)
    file_path = resource_filename(
        "mc_examples",
        "realistic_workflows/zeolite_adsorption/resources/lit_results/tjune_TON-methane_309K.txt",
    )
    lit_309K = np.genfromtxt(file_path, skip_header=1)

    for temperature in temperatures:
        zeo_ff_name = "june"
        avg_n = []
        for pressure in pressures:
            dirname = (
                f"zeo_ff_{zeo_ff_name}_T_{temperature:0.1f}_P_{pressure:0.2f}".
                replace(" ", "_").replace("/", "-"))
            thermo = ThermoProps(dirname + "/prod.out.prp")
            avg_n.append(np.mean(thermo.prop("Nmols_2")) / n_unitcells)
        avg_n = u.unyt_array(avg_n)
        prev_plt = ax.scatter(
            pressures.to_value("bar"),
            avg_n.value,
            label=f"{temperature:.0f} June",
            s=100,
        )

        zeo_ff_name = "trappe"
        avg_n = []
        for pressure in pressures:
            dirname = (
                f"zeo_ff_{zeo_ff_name}_T_{temperature:0.1f}_P_{pressure:0.2f}".
                replace(" ", "_").replace("/", "-"))
            thermo = ThermoProps(dirname + "/prod.out.prp")
            avg_n.append(np.mean(thermo.prop("Nmols_2")) / n_unitcells)
        avg_n = u.unyt_array(avg_n)
        ax.scatter(
            pressures.to_value("bar"),
            avg_n.value,
            marker="s",
            facecolors="none",
            edgecolors=prev_plt.get_facecolor()[0],
            label=f"{temperature:.0f} TraPPE",
            s=100,
        )

    ax.scatter(
        lit_298K[:, 0],
        lit_298K[:, 1],
        marker="1",
        label="Romanielo 2020 298 K",
        s=150,
    )
    ax.scatter(
        lit_309K[:, 0],
        lit_309K[:, 1],
        marker="2",
        label="Romanielo 2020 309 K",
        s=150,
    )

    ax.set_ylabel("$\mathregular{N_{methane}}$/unit cell",
                  fontsize=16,
                  labelpad=10)
    ax.set_xlabel("Pressure (bar)", fontsize=16, labelpad=10)
    ax.tick_params(which="both",
                   direction="in",
                   labelsize=14,
                   top=True,
                   right=True)
    ax.set_xscale("log")
    ax.set_ylim(0, 1.5)
    ax.yaxis.set_minor_locator(AutoMinorLocator(2))
    fig.legend(fontsize=14, loc="upper left", bbox_to_anchor=(0.18, 0.95))
    fig.tight_layout(pad=2.0)

    fig.savefig(outdir + f"/isotherm.pdf")
Beispiel #9
0
 def test_invalid_prop(self):
     thermo = ThermoProps(get_fn("equil.out.box1.prp"))
     with pytest.raises(ValueError, match=r"not an available"):
         chem_pot = thermo.prop("Chemical_Potential")
Beispiel #10
0
 def test_extract_prop(self):
     thermo = ThermoProps(get_fn("equil.out.box1.prp"))
     assert thermo.prop("Pressure").shape == (201,)
     assert np.isclose(thermo.prop("Pressure")[-1].value, 42.242944)
     assert np.isclose(thermo.prop("Energy_InterVDW")[0].value, 22378.33)
Beispiel #11
0
 def test_read_prp(self):
     thermo = ThermoProps(get_fn("equil.out.box1.prp"))
     assert thermo._data.shape == (201, 7)
     assert np.isclose(thermo._data[-1, 3], 42.242944)
     assert np.isclose(thermo._data[0, 2], 22378.33)
Beispiel #12
0
import unyt as u
import matplotlib.pyplot as plt
from mosdef_cassandra.analysis import ThermoProps
from matplotlib.ticker import MultipleLocator
from matplotlib import rcParams

rcParams['font.sans-serif'] = "Arial"
rcParams['font.family'] = "sans-serif"

thermo = ThermoProps("npt.out.prp")

fig, ax = plt.subplots()
ax.plot(
    thermo.prop("MC_STEP").value,
    thermo.prop("Pressure").to_value(u.MPa),
    color="black",
)

ax.set_xlabel("MC Step", fontsize=18, labelpad=15)
ax.set_ylabel("Pressure (MPa)", fontsize=18, labelpad=18)

ax.set_xlim(0, 300000)
ax.set_ylim(0, 14)
ax.xaxis.set_major_locator(MultipleLocator(75000))
ax.xaxis.set_minor_locator(MultipleLocator(25000))
ax.yaxis.set_major_locator(MultipleLocator(2))
ax.yaxis.set_minor_locator(MultipleLocator(1))
ax.tick_params(labelsize=16)
ax.tick_params(which="both", direction="in", right=True, top=True)
fig.tight_layout()
Beispiel #13
0
import unyt as u
import numpy as np
from mosdef_cassandra.analysis import ThermoProps
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, AutoMinorLocator
from matplotlib import rcParams
import seaborn

rcParams['font.sans-serif'] = "Arial"
rcParams['font.family'] = "sans-serif"

thermo_liq = ThermoProps("gemc.out.box1.prp")
thermo_vap = ThermoProps("gemc.out.box2.prp")

fig, ax = plt.subplots()
ax.plot(
    thermo_vap.prop("MC_STEP").value,
    thermo_vap.prop("Pressure").to_value(u.MPa),
    color="black",
)

ax.set_xlabel("MC Step", fontsize=18, labelpad=18)
ax.set_ylabel("Vapor pressure (MPa)", fontsize=18, labelpad=18)
ax.set_xticks(np.arange(0, 500001, 125000))
ax.tick_params(labelsize=16)
ax.tick_params(which="both", direction="in", right=True, top=True)
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
ax.set_xlim(0, 500000)
ax.set_ylim(0, 5.0)
fig.tight_layout()