Generate a cubic lattice.

    Args:
        a (Int):         Number of lattice repeat units along x.
        b (Int):         Number of lattice repeat units along y.
        c (Int):         Number of lattice repeat units along z.
        spacing (Float): Distance between lattice sites.

    Returns:
        (Lattice): The new lattice

def cubic_lattice( a, b, c, spacing ):
    """
    Generate a cubic lattice.

    Args:
        a (Int):         Number of lattice repeat units along x.
        b (Int):         Number of lattice repeat units along y.
        c (Int):         Number of lattice repeat units along z.
        spacing (Float): Distance between lattice sites.

    Returns:
        (Lattice): The new lattice
    """
    grid = np.array( list( range( 1, a * b * c + 1 ) ) ).reshape( a, b, c, order='F' )
    it = np.nditer( grid, flags=[ 'multi_index' ] )
    sites = []
    while not it.finished:
        x, y, z = it.multi_index
        r = np.array( [ x, y, z ] ) * spacing
        neighbours = [ np.roll( grid, +1, axis=0 )[x,y,z],
                       np.roll( grid, -1, axis=0 )[x,y,z],
                       np.roll( grid, +1, axis=1 )[x,y,z],
                       np.roll( grid, -1, axis=1 )[x,y,z],
                       np.roll( grid, +1, axis=2 )[x,y,z],
                       np.roll( grid, -1, axis=2 )[x,y,z] ]
        sites.append( lattice_site.Site( int( it[0] ), r, neighbours, 0.0, 'L' ) )
        it.iternext()
    return lattice.Lattice( sites, cell_lengths = np.array( [ a, b, c ] ) * spacing )