예제 #1
0
    def test_sidemax(self):
        from mbuild.lib.molecules import Methane
        ch4 = Methane()
        #With default sidemax
        box_of_methane = mb.fill_box(ch4,
                                     box=[1000, 1000, 1000],
                                     n_compounds=500)
        sphere_of_methane = mb.fill_sphere(ch4,
                                           sphere=[1000, 1000, 1000, 1000],
                                           n_compounds=500)
        assert all(box_of_methane.boundingbox.lengths < [110, 110, 110])
        assert all(sphere_of_methane.boundingbox.lengths < [210, 210, 210])

        #With adjusted sidemax
        big_box_of_methane = mb.fill_box(ch4,
                                         box=[1000, 1000, 1000],
                                         n_compounds=500,
                                         sidemax=1000.0)
        big_sphere_of_methane = mb.fill_sphere(ch4,
                                               sphere=[1000, 1000, 1000, 1000],
                                               n_compounds=500,
                                               sidemax=2000.0)
        assert all(big_box_of_methane.boundingbox.lengths > [900, 900, 900])
        assert all(
            big_sphere_of_methane.boundingbox.lengths > [1800, 1800, 1800])
예제 #2
0
    def test_validate_mass(self, methane):
        bead = mb.Compound(name="A", mass=0.0)
        with pytest.raises(MBuildError):
            mb.fill_box(compound=bead, n_compounds=10, density=1)

        with pytest.raises(MBuildError):
            mb.fill_box(compound=bead, density=1, box=[0.5, 0.5, 0.5])

        with pytest.raises(MBuildError):
            mb.fill_sphere(compound=bead, sphere=[20, 20, 20, 20], density=1)

        beadA = mb.Compound(name="A", mass=0.0)
        beadB = mb.Compound(name="B", mass=1.0, pos=[0.5, 0.5, 0.5])
        beads = mb.Compound(subcompounds=[beadA, beadB])
        with warnings.catch_warnings(record=True) as w:
            mb.packing._validate_mass(compound=[beadA, beadB],
                                      n_compounds=None)
            assert w

        with warnings.catch_warnings(record=True) as w:
            mb.packing._validate_mass(compound=[beads], n_compounds=None)
            assert w

        with warnings.catch_warnings(record=True) as w:
            mb.packing._validate_mass(compound=[beads], n_compounds=[5])
            assert w
예제 #3
0
    def test_fill_sphere(self, h2o):
        filled = mb.fill_sphere(h2o, sphere=[3, 3, 3, 1.5], n_compounds=50)
        assert filled.n_particles == 50 * 3
        assert filled.n_bonds == 50 * 2

        center = np.array([3.0, 3.0, 3.0])
        assert np.alltrue(np.linalg.norm(filled.xyz - center, axis=1) < 1.5)
예제 #4
0
    def test_fill_sphere(self, h2o):
        filled = mb.fill_sphere(h2o, sphere=[3, 3, 3, 1.5], n_compounds=50)
        assert filled.n_particles == 50 * 3
        assert filled.n_bonds == 50 * 2

        center = np.array([3.0, 3.0, 3.0])
        assert np.alltrue(np.linalg.norm(filled.xyz - center, axis=1) < 1.5)
예제 #5
0
    def test_box_edge(self, h2o, methane):
        system_box = mb.Box(lengths=(1.8, 1.8, 1.8))
        packed = mb.fill_box(compound=h2o,
                             n_compounds=100,
                             box=system_box,
                             edge=0.2)
        edge_sizes = system_box.lengths - packed.boundingbox.lengths
        assert np.allclose(edge_sizes, np.array([0.4]*3), atol=0.1)

        region = mb.fill_region(compound=h2o,
                                n_compounds=100,
                                region=system_box,
                                edge=0.2)
        edge_sizes = system_box.lengths - packed.boundingbox.lengths
        assert np.allclose(edge_sizes, np.array([0.4]*3), atol=0.1)

        sphere = mb.fill_sphere(compound=h2o,
                                n_compounds=100,
                                sphere=[2, 2, 2, 1],
                                edge=0.2)
        assert np.allclose(sphere.boundingbox.mins, np.array([1.2]*3), atol=0.1)
        assert np.allclose(sphere.boundingbox.maxs, np.array([2.8]*3), atol=0.1)

        solvated = mb.solvate(solvent=h2o,
                              solute=methane,
                              n_solvent=100,
                              box=system_box,
                              overlap=0.2)
        edge_sizes = system_box.lengths - solvated.boundingbox.lengths
        assert np.allclose(edge_sizes, np.array([0.4]*3), atol=0.1)
예제 #6
0
 def test_fill_sphere_compound_ratio(self, h2o, ethane):
     filled = mb.fill_sphere(compound=[h2o, ethane],
                             sphere=[3, 3, 3, 1.5],
                             density=800,
                             compound_ratio=[2, 1])
     n_ethane = len([c for c in filled.children if c.name == 'Ethane'])
     n_water = len([c for c in filled.children if c.name == 'H2O'])
     assert n_water / n_ethane == 2
예제 #7
0
    def test_box_edge(self, h2o, methane):
        system_box = mb.Box(lengths=(1.8, 1.8, 1.8))
        packed = mb.fill_box(compound=h2o,
                             n_compounds=100,
                             box=system_box,
                             edge=0.2)
        edge_sizes = np.subtract(system_box.lengths,
                                 packed.get_boundingbox().lengths)
        assert np.allclose(edge_sizes, np.array([0.4] * 3), atol=0.1)

        region = mb.fill_region(
            compound=h2o,
            n_compounds=100,
            region=system_box,
            edge=0.2,
            bounds=[system_box],
        )
        edge_sizes = np.subtract(system_box.lengths,
                                 packed.get_boundingbox().lengths)
        assert np.allclose(edge_sizes, np.array([0.4] * 3), atol=0.1)

        edge = 0.2
        bounds = [2, 2, 2, 1]
        sphere = mb.fill_sphere(compound=h2o,
                                n_compounds=100,
                                sphere=bounds,
                                edge=edge)
        target_diameter = (bounds[3] - edge) * 2
        assert np.allclose(sphere.maxs - sphere.mins,
                           np.array([target_diameter] * 3),
                           atol=0.1)

        solvated = mb.solvate(
            solvent=h2o,
            solute=methane,
            n_solvent=100,
            box=system_box,
            overlap=0.2,
        )
        edge_sizes = np.subtract(system_box.lengths,
                                 solvated.get_boundingbox().lengths)
        assert np.allclose(edge_sizes, np.array([0.4] * 3), atol=0.1)
    def __init__(self, radius=2, angle=90.0, fluid=None, density=None,
                lattice=None, lattice_compound=None, x=None, y=None):

        super(GrapheneDroplet, self).__init__()

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

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

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

        # Default to graphene lattice
        if lattice is None:

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

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

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

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

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

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

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

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

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

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

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

        sphere.remove(to_remove)

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

        self.add(sheet)
        self.add(sphere)
        self.periodicity[0] = sheet.periodicity[0]
        self.periodicity[1] = sheet.periodicity[1]
        self.periodicity[2] = radius * 5
예제 #9
0
 def test_fill_sphere_bad_args(self, h2o, ethane):
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, sphere=[4, 4, 4, 1])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o,
                        n_compounds=100,
                        density=100,
                        sphere=[4, 4, 4, 1])
     with pytest.raises(TypeError):
         mb.fill_sphere(compound=h2o, density=1000, sphere="yes")
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=[h2o, ethane],
                        n_compounds=1000,
                        sphere=[1, 1, 1, 4])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o,
                        n_compounds=[10, 10],
                        sphere=[1, 1, 1, 4])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, n_compounds=100, sphere=[1, 1, 1, 4])
예제 #10
0
 def test_fill_sphere_density(self, h2o):
     filled = mb.fill_sphere(h2o, sphere=[3, 3, 3, 1.5], density=1000)
     assert filled.n_particles == 921
예제 #11
0
 def test_fill_sphere_bad_args(self, h2o, ethane):
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, sphere=[4, 4, 4, 1])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, n_compounds=100,
             density=100, sphere=[4, 4, 4, 1])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, density=1000, sphere='yes')
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=[h2o, ethane], n_compounds=1000, sphere=[1, 1, 1, 4])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, n_compounds=[10, 10], sphere=[1, 1, 1, 4])
     with pytest.raises(ValueError):
         mb.fill_sphere(compound=h2o, n_compounds=100, sphere=[1, 1, 1, 4])
예제 #12
0
 def test_fill_sphere_compound_ratio(self, h2o, ethane):
     filled = mb.fill_sphere(compound=[h2o, ethane], sphere=[3, 3, 3, 1.5],
             density=800, compound_ratio=[2, 1])
     n_ethane = len([c for c in filled.children if c.name == 'Ethane'])
     n_water = len([c for c in filled.children if c.name == 'H2O'])
     assert n_water / n_ethane == 2
예제 #13
0
 def test_fill_sphere_density(self, h2o):
     filled = mb.fill_sphere(h2o, sphere=[3, 3, 3, 1.5], density=1000)
     assert filled.n_particles == 921