Beispiel #1
0
def interpolate_wo(wo_low, wo_high, parameter, h=0.01, tag=None):
    """Interpolates between two water-oil curves.

    The saturation endpoints for the curves must be known
    by the objects. They can be estimated by estimate_sorw() etc.
    or can be set manually for finer control.

    The interpolation algorithm is different left and right
    for saturation endpoints, and saturation endpoints are
    interpolated individually.

    Arguments:
        wo_low (WaterOil): a "low" case
        wo_high (WaterOil): a "high" case
        parameter (float): Between 0 and 1. 0 will return the low case, 1 will return
            the high case. Any number in between will return an interpolated curve
        h (float): Saturation step-size in interpolant. If defaulted, a value
            smaller than in the input curves are used, to preserve information.
        tag (string): Tag to associate to the constructed object. If None
            it will be automatically filled. Set to empty string to ensure no tag.

    Returns:
        A new oil-water curve

    """
    # Warning: Almost code duplication with corresponding _go function

    assert isinstance(wo_low, pyscal.WaterOil)
    assert isinstance(wo_high, pyscal.WaterOil)

    assert 0 <= parameter <= 1
    # Extrapolation is refused, but perhaps later implemented with truncation to (0,1)

    # Running fast mode if both interpolants have fast mode
    if wo_low.fast and wo_high.fast:
        fast = True
    else:
        fast = False

    # Constructs functions that works on normalized saturation interval
    krw1, kro1 = normalize_nonlinpart_wo(wo_low)
    krw2, kro2 = normalize_nonlinpart_wo(wo_high)
    pc1 = normalize_pc(wo_low)
    pc2 = normalize_pc(wo_high)

    # Construct a function that can be applied to both relperm values
    # and endpoints
    def weighted_value(a, b):
        return a * (1.0 - parameter) + b * parameter

    # Interpolate saturation endpoints
    swl_new = weighted_value(wo_low.swl, wo_high.swl)
    swcr_new = weighted_value(wo_low.swcr, wo_high.swcr)
    sorw_new = weighted_value(wo_low.sorw, wo_high.sorw)

    # Interpolate kr at saturation endpoints
    krwmax_new = weighted_value(wo_low.table["krw"].max(),
                                wo_high.table["krw"].max())
    krwend_new = weighted_value(krw1(1), krw2(1))
    kroend_new = weighted_value(kro1(1), kro2(1))

    # Construct the new WaterOil object, with interpolated
    # endpoints:
    wo_new = pyscal.WaterOil(swl=swl_new,
                             swcr=swcr_new,
                             sorw=sorw_new,
                             h=h,
                             fast=fast)

    # Add interpolated relperm data in nonlinear parts:
    wo_new.table["krw"] = weighted_value(krw1(wo_new.table["swn"]),
                                         krw2(wo_new.table["swn"]))
    wo_new.table["krow"] = weighted_value(kro1(wo_new.table["son"]),
                                          kro2(wo_new.table["son"]))

    wo_new.set_endpoints_linearpart_krw(krwend=krwend_new, krwmax=krwmax_new)
    wo_new.set_endpoints_linearpart_krow(kroend=kroend_new)

    # We need a new fit-for-purpose normalized swnpc, that ignores
    # the initial swnpc (swirr-influenced)
    wo_new.table["swn_pc_intp"] = (
        wo_new.table["sw"] - wo_new.table["sw"].min()) / (
            wo_new.table["sw"].max() - wo_new.table["sw"].min())
    wo_new.table["pc"] = weighted_value(pc1(wo_new.table["swn_pc_intp"]),
                                        pc2(wo_new.table["swn_pc_intp"]))

    wo_new.tag = _interpolate_tags(wo_low, wo_high, parameter, tag)

    return wo_new
Beispiel #2
0
def main():
    """Used for invocation on the command line"""
    parser = get_parser()
    args = parser.parse_args()

    warnings.warn("gen_satfunc is deprecated, use pyscal", FutureWarning)

    logger.setLevel(logging.INFO)

    if not Path(args.config_file).exists():
        sys.exit(f"Could not find the configuration file: {args.config_file}")

    output = ""

    for line in open(args.config_file).readlines():
        tmp = line.strip()
        if not tmp[0:2] == "--" and len(tmp) > 0:
            if tmp[0:7] == "RELPERM":

                # Parse relperm parameters from the rest of the line:
                relperm_input = tuple(tmp[8:].split("--")[0].split())
                relperm_input = [float(i) for i in relperm_input]

                if len(relperm_input) < 9:
                    logger.error("Too few relperm parameters in line:\n%s",
                                 line)
                    raise ValueError("Erroneous relperm parameters")

                # Unpack parameter list to explicitly named parameters:
                (Lw, Ew, Tw, Lo, Eo, To, Sorw, Swl, Krwo) = relperm_input[0:9]

                if len(relperm_input) > 9:
                    num_sw_steps = relperm_input[9]
                else:
                    num_sw_steps = 20

                wo = pyscal.WaterOil(h=1.0 / (num_sw_steps + 2),
                                     sorw=Sorw,
                                     swl=Swl)
                wo.add_LET_oil(Lo, Eo, To, kroend=1)
                wo.add_LET_water(Lw, Ew, Tw, krwend=Krwo)

                if 10 < len(relperm_input) < 15:
                    logger.error("Too few parameter for pc in line:\n%s", line)
                    raise ValueError("Erroneous pc parameters")

                if len(relperm_input) == 15:
                    (PERM, PORO, a, b, sigma_costau) = relperm_input[10:15]
                    wo.add_normalized_J(a=a,
                                        b=b,
                                        poro=PORO,
                                        perm=PERM,
                                        sigma_costau=sigma_costau)

                output += wo.SWOF(header=False)

            elif tmp[0:7] == "COMMENT":
                logger.info("Printing comment")
                comment = tmp[8:].split("--")[0]
                output = output + "--" + comment + "\n"
            elif tmp[0:4] == "SWOF":
                logger.info("Generating SWOF table")
                output = output + "SWOF\n"
            elif tmp[0:4] == "SGOF":
                logger.info("Generating SGOF table")
                output = output + "SGOF\n"
            else:
                raise ValueError('Error while interpreting line: "%s"' %
                                 line.strip())

    logger.info("Writing output file...")

    Path(args.output_file).write_text(output)

    logger.info("Done")