Skip to content

Commit

Permalink
Added support for PVDO and PVTG. (#529)
Browse files Browse the repository at this point in the history
* Added support for PVDO and PVTG.
* Updated comments and adjusted variable names in opm_init_io.py.
* Updated changelog.
  • Loading branch information
rubenthoms authored Dec 18, 2020
1 parent 4a30507 commit abc91e0
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 61 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#526](https://github.com/equinor/webviz-subsurface/pull/526) - Fixes to `SurfaceViewerFMU`. User defined map units are now correctly displayed. Map height can now be set (useful for maps with elongated geometry). Added some missing documentation
- [#531](https://github.com/equinor/webviz-subsurface/pull/531) - The change in [#505](https://github.com/equinor/webviz-subsurface/pull/505) resulted in potentially very large datasets when using `raw` sampling. Some users experienced `MemoryError`. `column_keys` filtering is therefore now used when loading and storing data if `sampling` is `raw` in plugins using `UNSMRY` data, most noticable in `BhpQc` which has `raw` as the default and only option.

### Added
- [#529](https://github.com/equinor/webviz-subsurface/pull/529) - Added support for PVDO and PVTG to PVT plot and to respective data modules.

## [0.1.6] - 2020-11-30
### Fixed
- [#505](https://github.com/equinor/webviz-subsurface/pull/505) - Fixed recent performance regression issue for loading of UNSMRY data. Loading times when multiple plugins are using the same data is now significantly reduced. Note that all UNSMRY vectors are now stored in portable apps, independent of choice of column_keys in individual plugins.
Expand Down
80 changes: 68 additions & 12 deletions webviz_subsurface/_datainput/opm_init_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def formation_volume_factor(
Does only return an empty list for now.
"""
if len(gas_oil_ratio) != len(pressure):
raise ValueError("rs and po arguments must be of same size")
raise ValueError("Rs / Rv and pressure arguments must be of same size")
return []

def viscosity(
Expand All @@ -135,6 +135,10 @@ class LiveOil(PvxOBase):
pass


class DeadOil(PvxOBase):
pass


class WetGas(PvxOBase):
pass

Expand Down Expand Up @@ -203,9 +207,8 @@ def create_pvt_function(
"Size mismatch in Condensed table data of PVT table for oil"
)

# For now, raise an exception if dead oil, since this is not supported yet
if raw.num_primary == 1:
raise super().InvalidType()
return self.create_dead_oil(raw)

return self.create_live_oil(raw)

Expand All @@ -222,6 +225,7 @@ def create_live_oil(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:

# PKey Inner C0 C1 C2 C3
# Rs Po 1/B 1/(B*mu) d(1/B)/dPo d(1/(B*mu))/dPo
# : : : : :

for index_primary in range(0, raw.num_primary):
if self.entry_valid(raw.primary_key[index_primary]):
Expand Down Expand Up @@ -259,6 +263,59 @@ def create_live_oil(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:

return ret

def create_dead_oil(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:
# Holding raw.num_tables values
ret: List[PvxOBase] = []

column_stride = raw.num_rows * raw.num_tables * raw.num_primary
table_stride = raw.num_primary * raw.num_rows

# pylint: disable=too-many-nested-blocks
for index_table in range(0, raw.num_tables):
values = []

# Key C0 C1 C2 C3
# Po 1/B 1/(B*mu) d(1/B)/dPo d(1/(B*mu))/dPo
# : : : :

# Dead oil does only have one primary index
# TODO(Ruben) Shall the structure be kept anyways?
for index_primary in range(0, raw.num_primary):
if self.entry_valid(raw.primary_key[index_primary]):
outer_value_pair = VariateAndValues()
outer_value_pair.x = raw.primary_key[index_primary]
# TODO(Ruben): Is there a better way to achieve this?
temp_list: List[VariateAndValues] = []
outer_value_pair.y = temp_list
for index_row in range(0, raw.num_rows):
pressure = raw.data[
column_stride * 0
+ index_table * table_stride
+ index_primary * raw.num_rows
+ index_row
]
if self.entry_valid(pressure):
inner_value_pair = VariateAndValues()
inner_value_pair.x = pressure
inner_value_pair.y = [0.0 for col in range(1, raw.num_cols)]
for index_column in range(1, raw.num_cols):
inner_value_pair.y[index_column - 1] = raw.data[
column_stride * index_column
+ index_table * table_stride
+ index_primary * raw.num_rows
+ index_row
]
outer_value_pair.y.append(inner_value_pair)
else:
break
else:
break

values.append(outer_value_pair)
ret.append(DeadOil(values))

return ret

@staticmethod
def from_ecl_init_file(ecl_init_file: EclFile) -> Optional["Oil"]:
logihead = ecl_init_file.__getitem__(InitFileDefinitions.LOGIHEAD_KW)
Expand Down Expand Up @@ -337,8 +394,9 @@ def create_dry_gas(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:
for index_table in range(0, raw.num_tables):
values = []

# PKey Inner C0 C1 C2 C3
# Rs Po 1/B 1/(B*mu) d(1/B)/dPo d(1/(B*mu))/dPo
# Key C0 C1 C2 C3
# Pg 1/B 1/(B*mu) d(1/B)/dRv d(1/(B*mu))/dRv
# : : : NaN NaN

for index_primary in range(0, raw.num_primary):
if self.entry_valid(raw.primary_key[index_primary]):
Expand Down Expand Up @@ -389,7 +447,8 @@ def create_wet_gas(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:
values = []

# PKey Inner C0 C1 C2 C3
# Rs Po 1/B 1/(B*mu) d(1/B)/dPo d(1/(B*mu))/dPo
# Pg Rv 1/B 1/(B*mu) d(1/B)/dPg d(1/(B*mu))/dPg
# : : : : :

for index_primary in range(0, raw.num_primary):
if self.entry_valid(raw.primary_key[index_primary]):
Expand All @@ -399,15 +458,15 @@ def create_wet_gas(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:
temp_list: List[VariateAndValues] = []
outer_value_pair.y = temp_list
for index_row in range(0, raw.num_rows):
pressure = raw.data[
r_v = raw.data[
column_stride * 0
+ index_table * table_stride
+ index_primary * raw.num_rows
+ index_row
]
if self.entry_valid(pressure):
if self.entry_valid(r_v):
inner_value_pair = VariateAndValues()
inner_value_pair.x = pressure
inner_value_pair.x = r_v
inner_value_pair.y = [0.0 for col in range(1, raw.num_cols)]
for index_column in range(1, raw.num_cols):
inner_value_pair.y[index_column - 1] = raw.data[
Expand Down Expand Up @@ -491,9 +550,6 @@ def create_water(self, raw: EclPropertyTableRawData) -> List[PvxOBase]:
for index_table in range(0, raw.num_tables):
values = []

# PKey Inner C0 C1 C2 C3
# Rs Po 1/B 1/(B*mu) d(1/B)/dPo d(1/(B*mu))/dPo

index_primary = 0
outer_value_pair = VariateAndValues()
outer_value_pair.x = 0
Expand Down
70 changes: 60 additions & 10 deletions webviz_subsurface/_datainput/pvt_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@
from webviz_config.common_cache import CACHE
from webviz_config.webviz_store import webvizstore

from .opm_init_io import Oil, Gas, Water, DryGas, VariateAndValues
from .opm_init_io import (
Oil,
Gas,
Water,
DryGas,
WetGas,
LiveOil,
DeadOil,
VariateAndValues,
)
from .fmu_input import load_ensemble_set, load_csv


Expand All @@ -37,19 +46,38 @@ def filter_pvt_data_frame(
) -> pd.DataFrame:

data_frame = data_frame.rename(str.upper, axis="columns").rename(
columns={"TYPE": "KEYWORD", "RS": "GOR"}
columns={
"TYPE": "KEYWORD",
"RS": "GOR",
"RSO": "GOR",
"R": "GOR",
"RV": "OGR",
}
)
data_frame = data_frame.fillna(0)
if "GOR" in data_frame.columns and "OGR" in data_frame.columns:
data_frame["RATIO"] = data_frame["GOR"] + data_frame["OGR"]
elif "GOR" in data_frame.columns:
data_frame["RATIO"] = data_frame["GOR"]
elif "OGR" in data_frame.columns:
data_frame["RATIO"] = data_frame["OGR"]

columns = [
"ENSEMBLE",
"REAL",
"PVTNUM",
"KEYWORD",
"GOR",
"RATIO",
"PRESSURE",
"VOLUMEFACTOR",
"VISCOSITY",
]

if not "RATIO" in data_frame.columns:
raise ValueError(
"The dataframe must contain a column for the ratio (OGR, GOR, R, RV, RS)."
)

data_frame = data_frame[columns]

stored_data_frames: List[pd.DataFrame] = []
Expand Down Expand Up @@ -123,6 +151,7 @@ def load_pvt_dataframe(
use_init_file: bool = False,
drop_ensemble_duplicates: bool = False,
) -> pd.DataFrame:
# pylint: disable=too-many-statements
# If ecl2df is not loaded, this machine is probably not
# running Linux and the modules are not available.
# To avoid a crash, return an empty DataFrame here.
Expand Down Expand Up @@ -159,13 +188,25 @@ def init_to_pvt_data_frame(kwargs: Any) -> pd.DataFrame:
column_keyword = []

if oil:
if len(oil.tables()) > 0 and isinstance(oil.tables()[0], LiveOil):
keyword = "PVTO"
elif len(oil.tables()) > 0 and isinstance(oil.tables()[0], DeadOil):
keyword = "PVDO"
else:
raise NotImplementedError(
f"Oil of type '{type(oil)}' is not supported yet."
)

for table_index, table in enumerate(oil.tables()):
for outer_pair in table.get_values():
for inner_pair in outer_pair.y:
if isinstance(inner_pair, VariateAndValues):
column_pvtnum.append(table_index + 1)
column_keyword.append("PVTO")
column_oil_gas_ratio.append(outer_pair.x)
column_keyword.append(keyword)
if isinstance(table, DeadOil):
column_oil_gas_ratio.append(0.0)
else:
column_oil_gas_ratio.append(outer_pair.x)
column_pressure.append(inner_pair.x)
column_volume_factor.append(
1.0 / inner_pair.get_values_as_floats()[0]
Expand All @@ -176,17 +217,26 @@ def init_to_pvt_data_frame(kwargs: Any) -> pd.DataFrame:
)

if gas:
if len(gas.tables()) > 0 and isinstance(gas.tables()[0], DryGas):
keyword = "PVDG"
elif len(gas.tables()) > 0 and isinstance(gas.tables()[0], WetGas):
keyword = "PVTG"
else:
raise NotImplementedError(
f"Gas of type '{type(gas)}' is not supported yet."
)
for table_index, table in enumerate(gas.tables()):
for outer_pair in table.get_values():
for inner_pair in outer_pair.y:
if isinstance(inner_pair, VariateAndValues):
column_pvtnum.append(table_index + 1)
column_keyword.append("PVDG")
column_keyword.append(keyword)
if isinstance(table, DryGas):
column_oil_gas_ratio.append(0)
column_oil_gas_ratio.append(0.0)
column_pressure.append(inner_pair.x)
else:
column_oil_gas_ratio.append(outer_pair.x)
column_pressure.append(inner_pair.x)
column_oil_gas_ratio.append(inner_pair.x)
column_pressure.append(outer_pair.x)
column_volume_factor.append(
1.0 / inner_pair.get_values_as_floats()[0]
)
Expand Down Expand Up @@ -216,7 +266,7 @@ def init_to_pvt_data_frame(kwargs: Any) -> pd.DataFrame:
{
"PVTNUM": column_pvtnum,
"KEYWORD": column_keyword,
"RS": column_oil_gas_ratio,
"R": column_oil_gas_ratio,
"PRESSURE": column_pressure,
"VOLUMEFACTOR": column_volume_factor,
"VISCOSITY": column_viscosity,
Expand Down
Loading

0 comments on commit abc91e0

Please sign in to comment.