def voigt_reuss(mod1: float, mod2: float, vfrac: float) -> tuple:
    """
    Computes the Voigt-Reuss-Hill bounds and average for a 2-component mixture.
    The Voigt Bound is obtained by assuming the strain field remains constant
    throughout the material when subjected to an arbitrary average stress field.
    The Reuss Bound is obtained by assuming the stress field remains constant
    throughout the material in an arbitrary average strain field.

    :param mod1: elastic modulus of first mineral
    :param mod2: elastic modulus of second mineral
    :param vfrac: volumetric fraction of first mineral (net-to-gross)
    :return: upper bound, lower bound, Voigt-Ruess-Hill average

    Reference
        Mavko, G, T. Mukerji and J. Dvorkin (2009), The Rock Physics Handbook: Cambridge University Press.
    """
    voigt = vfrac * mod1 + (1 - vfrac) * mod2
    reuss = 1 / (vfrac / mod1 + (1 - vfrac) / mod2)
    vrh = (voigt + reuss) / 2
    return voigt, reuss, vrh