def populate(self, compound_dict=None, x=1, y=1, z=1):
        """Expand lattice and create compound from lattice.

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

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

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

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

        Call Restrictions
        -----------------
        Called after constructor by user.
        """
        error_dict = {0: 'X', 1: 'Y', 2: 'Z'}
        try:
            x = int(x)
            y = int(y)
            z = int(z)
        except (ValueError, TypeError):
            raise ValueError('Cannot convert replication amounts into '
                             'integers. x= {}, y= {}, z= {} needs to '
                             'be an int.'.format(x, y, z))

        for replication_amount in x, y, z:
            if replication_amount is None:
                raise ValueError('Attempt to replicate None times. '
                                 'None is not an acceptable replication '
                                 'amount, 1 is the default.')

        for replication_amount, index in zip([x, y, z], range(3)):
            if replication_amount < 1:
                raise ValueError('Incorrect populate value: {} : {} is < 1. '
                                 .format(error_dict[index],
                                         replication_amount))

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

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

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

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

        for key, locations in self.lattice_points.items():
            for coords in locations:
                for replication in it.product(range(x), range(y), range(z)):
                    temp_location = list()

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

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

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

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

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

        ret_lattice = mb.Compound()

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

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

        return ret_lattice
Expand lattice and create compound from lattice.

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

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

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

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

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