Esempio n. 1
0
def df2ecl_pvto(dframe, comment=None):
    """Print PVTO-data from a dataframe

    Args:
        dframe (pd.DataFrame): Containing PVTO data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVTO\n"
    string += common.comment_formatter(comment)
    string += "-- {:^22} {:^22} {:^22} {:^22}\n".format(
        "RS", "PRESSURE", "VOLUMEFACTOR", "VISCOSITY"
    )
    string += "-- {:^22} {:^22} {:^22} {:^22}\n".format(
        "*", "PRESSURE", "VOLUMEFACTOR", "VISCOSITY"
    )
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVTO"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()

    def _pvto_pvtnum(dframe):
        """Print PVTO-data for a specific PVTNUM"""
        string = ""
        dframe = dframe.set_index("RS").sort_index()
        for rs in dframe.index.unique():
            string += _pvto_pvtnum_rs(dframe[dframe.index == rs])
        return string + "/\n"

    def _pvto_pvtnum_rs(dframe):
        """Print PVTO-data for a particular RS"""
        string = ""
        assert len(dframe.index.unique()) == 1
        rs = dframe.index.values[0]
        string += "{:20.7f}  ".format(rs)
        for rowidx, row in dframe.reset_index().iterrows():
            if rowidx > 0:
                indent = "\n" + " " * 22
            else:
                indent = ""
            string += (
                indent
                + "{PRESSURE:20.7f}  {VOLUMEFACTOR:20.7f}  {VISCOSITY:20.7f}".format(
                    **(row.to_dict())
                )
            )
        string += " /\n-- End RS={}\n".format(rs)
        return string

    for pvtnum in subset.index.unique():
        string += _pvto_pvtnum(subset[subset.index == pvtnum])
    return string + "\n"
Esempio n. 2
0
def df2ecl_pvtw(dframe, comment=None):
    """Print PVTW keyword with data

    PVTW is one line/record with data for a reference pressure
    for each PVTNUM.

    Args:
        dframe (pd.DataFrame): Containing PVTW data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVTW\n"
    string += common.comment_formatter(comment)
    string += "--   {:^21} {:^21} {:^21} {:^21} {:^21}  \n".format(
        "PRESSURE", "VOLUMEFACTOR", "COMPRESSIBILITY", "VISCOSITY", "VISCOSIBILITY"
    )
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVTW"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()
    for _, row in subset.iterrows():
        string += "  {PRESSURE:20.7f} {VOLUMEFACTOR:20.7f} ".format(**(row.to_dict()))
        string += "{COMPRESSIBILITY:20.7f} {VISCOSITY:20.7f} ".format(**(row.to_dict()))
        string += "{VISCOSIBILITY:20.7f}/\n".format(**(row.to_dict()))
    return string + "\n"
Esempio n. 3
0
def df2ecl_pvtg(dframe, comment=None):
    """Print DENSITY keyword with data

    DENSITY is one line (one record) of data pr. PVTNUM

    Args:
        dframe (pd.DataFrame): Containing PVTG data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "DENSITY\n"
    string += common.comment_formatter(comment)
    string += "--   {:^21} {:^21} {:^21}  \n".format(
        "OILDENSITY", "WATERDENSITY", "GASDENSITY"
    )
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "DENSITY"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()
    for _, row in subset.iterrows():
        string += "  {OILDENSITY:20.7f} {WATERDENSITY:20.7f} ".format(**(row.to_dict()))
        string += "{GASDENSITY:20.7f} /\n".format(**(row.to_dict()))
    return string + "\n"
Esempio n. 4
0
def _df2ecl_satfuncs(keyword: str,
                     dframe: pd.DataFrame,
                     comment: Optional[str] = None) -> str:
    if dframe.empty:
        return "-- No data!\n"
    string = "{}\n".format(keyword)
    string += common.comment_formatter(comment)

    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == keyword]
    if "SATNUM" not in subset:
        subset["SATNUM"] = 1
    subset = subset.set_index("SATNUM").sort_index()

    # Make a function that is to be called for each SATNUM
    def _df2ecl_satfuncs_satnum(keyword, dframe):
        """Print one saturation function for one specific SATNUM"""
        col_headers = RENAMERS[keyword]["DATA"]
        string = ("-- " + dframe[col_headers].to_string(
            float_format=" %g", header=True, index=False).strip())
        return string + "\n/\n"

    # Loop over every SATNUM
    for satnum in subset.index.unique():
        string += "-- SATNUM: {}\n".format(satnum)
        string += _df2ecl_satfuncs_satnum(keyword,
                                          subset[subset.index == satnum])
    return string + "\n"
Esempio n. 5
0
def df2ecl_rock(dframe, comment=None):
    """Print ROCK keyword with data

    Args:
        dframe (pd.DataFrame): Containing ROCK data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "ROCK\n"
    string += common.comment_formatter(comment)
    string += "--   {:^21} {:^21}\n".format("PRESSURE", "COMPRESSIBILITY")
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "ROCK"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()
    for _, row in subset.iterrows():
        string += "  {PRESSURE:20.7f} {COMPRESSIBILITY:20.7f} /\n".format(
            **(row.to_dict())
        )
    return string + "\n"
Esempio n. 6
0
def df2ecl_pvtw(dframe: pd.DataFrame, comment: Optional[str] = None) -> str:
    """Print PVTW keyword with data

    PVTW is one line/record with data for a reference pressure
    for each PVTNUM.

    Args:
        dframe: Containing PVTW data
        comment: Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVTW\n"
    string += common.comment_formatter(comment)
    string += (
        f"--   {'PRESSURE':^21} {'VOLUMEFACTOR':^21} {'COMPRESSIBILITY':^21} "
        f"{'VISCOSITY':^21} {'VISCOSIBILITY':^21}\n")
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVTW"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical(
                "If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()
    for _, row in subset.iterrows():
        string += f"  {row['PRESSURE']:20.7f} {row['VOLUMEFACTOR']:20.7f} "
        string += f"{row['COMPRESSIBILITY']:20.7f} {row['VISCOSITY']:20.7f} "
        string += f"{row['VISCOSIBILITY']:20.7f}/\n"
    return string + "\n"
Esempio n. 7
0
def df2ecl_density(dframe: pd.DataFrame, comment: Optional[str] = None) -> str:
    """Print DENSITY keyword with data

    Args:
        dframe: Containing DENSITY data
        comment: Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "DENSITY\n"
    string += common.comment_formatter(comment)
    string += f"--   {'OILDENSITY':^21} {'WATERDENSITY':^21} {'GASDENSITY':^21}\n"
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "DENSITY"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical(
                "If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()
    for _, row in subset.iterrows():
        string += f"  {row['OILDENSITY']:20.7f} {row['WATERDENSITY']:20.7f}"
        string += f" {row['GASDENSITY']:20.7f} /\n"
    return string + "\n"
Esempio n. 8
0
def df2ecl_equil(dframe, comment=None):
    """Print EQUIL keyword with data

    Args:
        dframe (pd.DataFrame): Containing EQUIL data
        comment (str): Text that will be included as a comment
    """
    string = "EQUIL\n"
    string += common.comment_formatter(comment)

    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "EQUIL"]
    if "EQLNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If EQLNUM is not supplied, only one row should be given")
            return ""
        subset["EQLNUM"] = 1
    subset = subset.set_index("EQLNUM").sort_index()

    phases = phases_from_columns(subset.columns)

    # Make a copy as we are going to modify it in order to have Pandas
    # make a pretty txt table:
    equildf = subset.copy()
    # Column names are pr. ec2ldf standard, redo to opm.common in order
    # to use sorting from that:
    inv_renamer = {value: key for key, value in RENAMERS[phases].items()}
    # print(inv_renamer)
    equildf.rename(inv_renamer, axis="columns", inplace=True)
    col_headers = [item["name"] for item in common.OPMKEYWORDS["EQUIL"]["items"]]
    for colname in col_headers:
        # Add those that are missing, as Eclipse defaults
        if colname not in equildf:
            equildf[colname] = "1*"
    # Reorder columns:
    equildf = equildf[col_headers]

    # It is critical for opm.common, maybe also E100 to have integers printed
    # as integers, for correct parsing. Ensure integer types where
    # the json says integer:
    integer_cols = [
        item["name"]
        for item in common.OPMKEYWORDS["EQUIL"]["items"]
        if item["value_type"] == "INT"
    ]
    for int_col in integer_cols:
        # But allow these columns to contain "1*"
        if set(equildf[int_col]) != {"1*"}:
            equildf[int_col] = equildf[int_col].astype(int)

    # Now rename again to have prettier column names:
    equildf.rename(RENAMERS[phases], axis="columns", inplace=True)
    # Add a final column with the end-slash, invisible header:
    equildf[" "] = "/"
    string += "-- " + equildf.to_string(header=True, index=False)
    return string + "\n\n"
Esempio n. 9
0
def df2ecl_pvtg(dframe: pd.DataFrame, comment: Optional[str] = None) -> str:
    """Print PVTG keyword with data

    Args:
        dframe: Containing PVTG data
        comment: Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVTG\n"
    string += common.comment_formatter(comment)
    string += "-- {:^22} {:^22} {:^22} {:^22}\n".format(
        "PRESSURE", "OGR", "VOLUMEFACTOR", "VISCOSITY")
    string += "-- {:^22} {:^22} {:^22} {:^22}\n".format(
        "*", "OGR", "VOLUMEFACTOR", "VISCOSITY")
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVTG"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical(
                "If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()

    def _pvtg_pvtnum(dframe):
        """Print PVTG-data for a specific PVTNUM"""
        string = ""
        dframe = dframe.set_index("PRESSURE").sort_index()
        for p_gas in dframe.index.unique():
            string += _pvtg_pvtnum_pg(dframe[dframe.index == p_gas])
        return string + "/\n"

    def _pvtg_pvtnum_pg(dframe):
        """Print PVTG-data for a particular gas phase pressure"""
        string = ""
        assert len(dframe.index.unique()) == 1
        p_gas = dframe.index.values[0]
        string += "{:20.7f}  ".format(p_gas)
        for rowidx, row in dframe.reset_index().iterrows():
            if rowidx > 0:
                indent = "\n" + " " * 22
            else:
                indent = ""
            string += (
                indent +
                "{OGR:20.7f}  {VOLUMEFACTOR:20.7f}  {VISCOSITY:20.7f}".format(
                    **(row.to_dict())))
        string += " /\n-- End PRESSURE={}\n".format(p_gas)
        return string

    for pvtnum in subset.index.unique():
        string += _pvtg_pvtnum(subset[subset.index == pvtnum])
    return string + "\n"
Esempio n. 10
0
def df2ecl_pvto(dframe: pd.DataFrame, comment: Optional[str] = None) -> str:
    """Print PVTO-data from a dataframe

    Args:
        dframe: Containing PVTO data
        comment: Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVTO\n"
    string += common.comment_formatter(comment)
    string += "-- {'RS':^22} {'PRESSURE':^22} {'VOLUMEFACTOR':^22} {'VISCOSITY':^22}\n"
    string += "-- {'*':^22} {'PRESSURE':^22} {'VOLUMEFACTOR':^22} {'VISCOSITY':^22}\n"
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVTO"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical(
                "If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1
    subset = subset.set_index("PVTNUM").sort_index()

    def _pvto_pvtnum(dframe: pd.DataFrame) -> str:
        """Print PVTO-data for a specific PVTNUM"""
        string = ""
        dframe = dframe.set_index("RS").sort_index()
        for rs in dframe.index.unique():
            string += _pvto_pvtnum_rs(dframe[dframe.index == rs])
        return string + "/\n"

    def _pvto_pvtnum_rs(dframe: pd.DataFrame) -> str:
        """Print PVTO-data for a particular RS"""
        string = ""
        assert len(dframe.index.unique()) == 1
        rs = dframe.index.values[0]
        string += f"{rs:20.7f}  "
        for rowidx, row in dframe.reset_index().iterrows():
            if rowidx > 0:
                indent = "\n" + " " * 22
            else:
                indent = ""
            string += (
                indent +
                f"{row['PRESSURE']:20.7f}  {row['VOLUMEFACTOR']:20.7f}  " +
                f"{row['VISCOSITY']:20.7f}")
        string += f" /\n-- End RS={rs}\n"
        return string

    for pvtnum in subset.index.unique():
        string += _pvto_pvtnum(subset[subset.index == pvtnum])
    return string + "\n"
Esempio n. 11
0
def df2ecl_pvdo(dframe, comment=None):
    """Print PVDO keyword with data

    Args:
        dframe (pd.DataFrame): Containing PVDO data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVDO\n"
    string += common.comment_formatter(comment)
    string += "--   {:^21} {:^21} {:^21}  \n".format(
        "PRESSURE", "VOLUMEFACTOR", "VISCOSITY"
    )
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVDO"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical("If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1

    def _pvdo_pvtnum(dframe):
        """Print PVDO-data for a specific PVTNUM

        Args:
            dframe (pd.DataFrame): Cropped to only contain the relevant data.

        Returns:
            string
        """
        string = ""
        dframe = dframe.sort_values("PRESSURE")
        for _, row in dframe.iterrows():
            string += "  {PRESSURE:20.7f} {VOLUMEFACTOR:20.7f} ".format(
                **(row.to_dict())
            )
            string += "{VISCOSITY:20.7f}\n".format(**(row.to_dict()))
        return string + "/\n"

    subset = subset.set_index("PVTNUM").sort_index()
    for pvtnum in subset.index.unique():
        string += "-- PVTNUM: {}\n".format(pvtnum)
        string += _pvdo_pvtnum(subset[subset.index == pvtnum])

    return string + "\n"
Esempio n. 12
0
def df2ecl_pvdg(dframe, comment=None):
    """Print PVDG keyword with data

    This data consists of one table (volumefactor and visosity
    as a function of pressure) pr. PVTNUM.

    Args:
        dframe (pd.DataFrame): Containing PVDG data
        comment (str): Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVDG\n"
    string += common.comment_formatter(comment)
    string += "--   {:^21} {:^21} {:^21}  \n".format(
        "PRESSURE", "VOLUMEFACTOR", "VISCOSITY"
    )
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVDG"]
    if "PVTNUM" not in subset:
        subset["PVTNUM"] = 1

    def _pvdg_pvtnum(dframe):
        """Print PVDG-data for a specific PVTNUM

        Args:
            dframe (pd.DataFrame): Cropped to only contain the relevant data.

        Returns:
            string
        """
        string = ""
        dframe = dframe.sort_values("PRESSURE")
        for _, row in dframe.iterrows():
            string += "  {PRESSURE:20.7f} {VOLUMEFACTOR:20.7f} ".format(
                **(row.to_dict())
            )
            string += "{VISCOSITY:20.7f}\n".format(**(row.to_dict()))
        return string + "/\n"

    subset = subset.set_index("PVTNUM").sort_index()
    for pvtnum in subset.index.unique():
        string += "-- PVTNUM: {}\n".format(pvtnum)
        string += _pvdg_pvtnum(subset[subset.index == pvtnum])

    return string + "\n"
Esempio n. 13
0
def df2ecl_pvdg(dframe: pd.DataFrame, comment: Optional[str] = None) -> str:
    """Print PVDG keyword with data

    This data consists of one table (volumefactor and visosity
    as a function of pressure) pr. PVTNUM.

    Args:
        dframe: Containing PVDG data
        comment: Text that will be included as a comment
    """
    if dframe.empty:
        return "-- No data!"
    string = "PVDG\n"
    string += common.comment_formatter(comment)
    string += f"--   {'PRESSURE':^21} {'VOLUMEFACTOR':^21} {'VISCOSITY':^21}  \n"
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == "PVDG"]
    if "PVTNUM" not in subset:
        if len(subset) != 1:
            logger.critical(
                "If PVTNUM is not supplied, only one row should be given")
            return ""
        subset["PVTNUM"] = 1

    def _pvdg_pvtnum(dframe):
        """Print PVDG-data for a specific PVTNUM

        Args:
            dframe (pd.DataFrame): Cropped to only contain the relevant data.

        Returns:
            string
        """
        string = ""
        dframe = dframe.sort_values("PRESSURE")
        for _, row in dframe.iterrows():
            string += f"  {row['PRESSURE']:20.7f} {row['VOLUMEFACTOR']:20.7f} "
            string += f"{row['VISCOSITY']:20.7f}\n"
        return string + "/\n"

    subset = subset.set_index("PVTNUM").sort_index()
    for pvtnum in subset.index.unique():
        string += "-- PVTNUM: {pvtnum}\n"
        string += _pvdg_pvtnum(subset[subset.index == pvtnum])

    return string + "\n"
Esempio n. 14
0
def _df2ecl_equilfuncs(keyword: str,
                       dframe: pd.DataFrame,
                       comment: Optional[str] = None) -> str:
    """Internal function to be used by df2ecl_<keyword>() functions"""
    if dframe.empty:
        return "-- No data!"
    string = "{}\n".format(keyword)
    string += common.comment_formatter(comment)
    col_headers = RENAMERS[keyword]["DATA"]

    string += "--   {:^21} {:^21} \n".format("DEPTH", col_headers[1])
    if "KEYWORD" not in dframe:
        # Use everything..
        subset = dframe
    else:
        subset = dframe[dframe["KEYWORD"] == keyword]
    if "EQLNUM" not in subset:
        subset["EQLNUM"] = 1

    def _df2ecl_equilfuncs_eqlnum(dframe: pd.DataFrame) -> str:
        """Print one equilibriation function table for a specific
        EQLNUM

        Args:
            dframe (pd.DataFrame): Cropped to only contain data for one EQLNUM

        Returns:
            string
        """
        string = ""
        dframe = dframe.sort_values("Z")
        for _, row in dframe.iterrows():
            string += "  {:20.7f} {:20.7f}\n".format(row[col_headers[0]],
                                                     row[col_headers[1]])
        return string + "/\n"

    subset = subset.set_index("EQLNUM").sort_index()
    for eqlnum in subset.index.unique():
        string += "-- EQLNUM: {}\n".format(eqlnum)
        string += _df2ecl_equilfuncs_eqlnum(subset[subset.index == eqlnum])
    return string + "\n"
Esempio n. 15
0
def df2ecl(grid_df,
           keywords,
           eclfiles=None,
           dtype=None,
           filename=None,
           nocomments=False):
    """
    Write an include file with grid data keyword, like PERMX, PORO,
    FIPNUM etc, for the GRID section of the Eclipse deck.

    Output (returned as string and optionally written to file) will then
    contain f.ex::

        PERMX
           3.3 4.1 500.1 8543.0 1223.0 5022.0
           411.455 4433.9
        /

    if the grid contains 8 cells (inactive and active).

    Args:
        grid_df (pd.DataFrame). Dataframe with the keyword for which
            we want to export data, and also the a column with GLOBAL_INDEX.
            Without GLOBAL_INDEX, the output will likely be invalid.
            The grid can contain both active and inactive cells.
        keywords (str or list of str): The keyword(s) to export, with one
            value for every cell.
        eclfiles (EclFiles): If provided, the total cell count for the grid
            will be requested from this object. If not, it will be *guessed*
            from the maximum number of GLOBAL_INDEX, which can be under-estimated
            in the corner-case that the last cells are inactive.
        dtype (float or int-class): If provided, the columns which are
            outputted are converted to int or float. Dataframe columns
            read from CSV files easily gets the wrong type, while Eclipse
            might require some data to be strictly integer.
        filename (str): If provided, the string produced will also to be
            written to this filename.
        nocomments (bool): Set to True to avoid any comments being written. Defaults
            to False.
    """
    if isinstance(keywords, str):
        keywords = [keywords]

    if isinstance(dtype, str):
        if dtype.startswith("int"):
            dtype = int
        elif dtype.startswith("float"):
            dtype = float
        else:
            raise ValueError("Wrong dtype argument {}".format(dtype))

    # Figure out the total number of cells for which we need to export data for:
    global_size = None
    active_cells = None
    if eclfiles is not None:
        if eclfiles.get_egrid() is not None:
            global_size = eclfiles.get_egrid().get_global_size()
            active_cells = eclfiles.get_egrid().getNumActive()

    if "GLOBAL_INDEX" not in grid_df:
        logger.warning(("Global index not found in grid dataframe. "
                        "Assumes all cells are active"))
        # Drop NaN rows for columns to be used (triggerd by stacked
        # dates and no global index, unlikely)
        # Also copy dataframe to avoid side-effects on incoming data.
        grid_df = grid_df.dropna(
            axis="rows",
            subset=[keyword for keyword in keywords if keyword in grid_df])
        grid_df["GLOBAL_INDEX"] = grid_df.index

    if global_size is None:
        global_size = int(grid_df["GLOBAL_INDEX"].max() + 1)
        active_cells = len(grid_df[grid_df.index >= 0])
        logger.warning("Global grid size estimated to %s", str(global_size))

    ecl2df_header = ("Output file printed by " + "ecl2df.grid " + __version__ +
                     "\n" + " at " + str(datetime.datetime.now()))

    string = ""
    if not nocomments:
        string += common.comment_formatter(ecl2df_header)
    string += "\n"

    # If we have NaNs in the dataframe, we will be more careful (costs memory)
    if grid_df.isna().any().any():
        grid_df = grid_df.dropna(
            axis="rows",
            subset=[keyword for keyword in keywords if keyword in grid_df])

    for keyword in keywords:
        if keyword not in grid_df.columns:
            raise ValueError(
                "Keyword {} not found in grid dataframe".format(keyword))
        vector = np.zeros(global_size)
        vector[grid_df["GLOBAL_INDEX"].astype(int).values] = grid_df[keyword]
        if dtype == int:
            vector = vector.astype(int)
        if dtype == float:
            vector = vector.astype(float)
        if len(vector) != global_size:
            logger.warning(
                ("Mismatch between dumped vector length "
                 "%d from df2ecl and assumed grid size %d"),
                len(vector),
                global_size,
            )
            logger.warning("Data will be dumped, but may error in simulator")
        strvector = "  ".join([str(x) for x in vector])
        strvector = common.runlength_eclcompress(strvector)

        string += keyword + "\n"
        indent = " " * 5
        string += "\n".join(
            textwrap.wrap(strvector,
                          initial_indent=indent,
                          subsequent_indent=indent,
                          width=70))
        string += "\n/"
        if not nocomments:
            string += " -- {}: {} active cells, {} total cell count\n".format(
                keyword, active_cells, global_size)
        string += "\n"

    if filename is not None:
        # Make directory if not present:
        filenamedir = os.path.dirname(filename)
        if filenamedir and not os.path.exists(filenamedir):
            os.makedirs(filenamedir)
        with open(filename, "w") as file_handle:
            file_handle.write(string)

    return string
Esempio n. 16
0
def df2ecl_editnnc(nnc_df, filename=None, nocomments=False):
    """Write an EDITNNC keyword

    This will write
        EDITNNC
           IX IY IZ JX JY JZ TRANM /
           ...
        /

    and return as string and/or dump to filename.

    The column TRANM must be in the incoming dataframe
    and it should be the multiplier to be written for
    each connection.

    If you want to edit only a subset of the non-neighbour
    connections, filter the dataframe upfront.

    Only rows where the column "DIR" is "NNC" will be considered.

    Args:
        nnc_df (pd.DataFrame): Dataframe with I1, J1, K1, I2, J2, K2 and a TRANM
            column, where the multiplier to be written is in TRANM. If the DIR
            column is present, only the rows with 'NNC' in the DIR column
            are included.
        filename (str): Filename to write to
        nocomments (bool): Set to True if you don't want any comments
            in the produced string/file

    Returns:
        string with the EDITNNC keyword.
    """

    string = ""
    ecl2df_header = ("Output file printed by ecl2df.nnc" + " " + __version__ +
                     "\n" + " at " + str(datetime.datetime.now()))
    if not nocomments:
        string += common.comment_formatter(ecl2df_header)
    string += "\n"

    if "DIR" in nnc_df:
        nnc_df = nnc_df[nnc_df["DIR"] == "NNC"]

    if "TRANM" not in nnc_df:
        raise ValueError("TRANM not supplied in nnc_df")
    string += "EDITNNC" + os.linesep
    table_str = nnc_df[["I1", "J1", "K1", "I2", "J2", "K2",
                        "TRANM"]].to_string(header=True, index=False)
    lines = table_str.rstrip().split(os.linesep)
    indent = "   "
    string += "-- " + lines[0] + os.linesep
    string += os.linesep.join([indent + line + " /" for line in lines[1:]])
    string += os.linesep
    string += "/"
    if not nocomments:
        string += " "
        string += common.comment_formatter(
            "  {} nnc connections, avg multiplier {}".format(
                len(nnc_df), nnc_df["TRANM"].mean()))
    string += "\n\n"

    if filename is not None:
        # Make directory if not present:
        filenamedir = os.path.dirname(filename)
        if filenamedir and not os.path.exists(filenamedir):
            os.makedirs(filenamedir)
        with open(filename, "w") as file_handle:
            file_handle.write(string)

    return string