def calc_J(df_clust):
    """Calculate the total angular momentum of the cluster::

            N
        J = Σ r_i × m_i * v_i
           i=1

    :param df_clust: cluster data - position, velocity, and mass
    :type df_clust: pyspark.sql.DataFrame, with schema schemas.clust
    :returns: J, broken into components
    :rtype: {[type]}
    """

    df_J = df_clust.selectExpr("x", "y", "z",
                               "`m` * `vx` as `mvx`",
                               "`m` * `vy` as `mvy`",
                               "`m` * `vz` as `mvz`"
                               )
    # cross product
    df_J = df_J.selectExpr("`y` * `mvz` - `z` * `mvy` as `Jx`",
                           "`z` * `mvx` - `x` * `mvz` as `Jy`",
                           "`x` * `mvy` - `y` * `mvx` as `Jz`")

    df_J = df_J.groupBy().sum()
    renameCols = [f"`sum({col})` as `{col}`" for col in ['Jx', 'Jy', 'Jz']]

    return df_J.selectExpr(*renameCols).collect()[0]