pyscal package¶
Submodules¶
pyscal.constants module¶
Constants used for pyscal modules:
SWINTEGERS
: Number of different Sw values within [0,1] we allow This is used to create integer indices of Sw, since Floating Point indices are flaky in Pandas (and in general on computers)EPSILON
: Used as “a small number” for ensuring no floating point comparisons/errors pop up. You cannot have the h parameter less than this when generating relperm tablesMAX_EXPONENT
: Maximal number for exponents in relperm parametrizations. Used to avoid numerical instabilities. It could probably be much higher than the chosen number in most circumstances, but such high numbers should not be relevant for relative permeability
pyscal.factory module¶
Factory functions for creating the pyscal objects

pyscal.factory.
slicedict
(dct, keys)[source]¶ Slice a dictionary for a set of keys. Keys not existing will be ignored.

class
pyscal.factory.
PyscalFactory
[source]¶ Bases:
object
Class for implementing the factory pattern for Pyscal objects
The factory functions herein can take multiple parameter sets, determine what kind of parametrization to be used, and set up the full objects based on these parameters, instead of explicitly having to call the API for each task.
Example:
wo = WaterOil(sorw=0.05) wo.add_corey_water(nw=3) wo.add_corey_oil(now=2) # is equivalent to: wo = factory.create_water_oil(dict(sorw=0.05, nw=3, now=2))
Parameter names to factory functions are case insensitive, while the add_*() parameters are not. This is becase the add_*() parameters are meant as a Python API, while the factory class is there to aid users when input is written in a different context, like an Excel spreadsheet.

static
create_water_oil
(params=None)[source]¶ Create a WaterOil object from a dictionary of parameters.
Parameterization (Corey/LET) is inferred from presence of certain parameters in the dictionary.
Don’t rely on behaviour of you supply both Corey and LET at the same time.
Parameter names in the dictionary are case insensitive. You can use Swirr, swirr, sWirR, swiRR etc.
NB: the add_LET_* methods have the names ‘l’, ‘e’ and ‘t’ in their signatures, which is not precise enough in this context, so we require e.g. ‘Lw’ and ‘Low’ (which both will be translated to ‘l’)
 Recognized parameters:
swirr, swl, swcr, sorw, h, tag, nw, now, krwmax, krwend, lw, ew, tw, low, eow, tow, lo, eo, to, kromax, krowend, a, b, poro_ref, perm_ref, drho, a, b, poro, perm, sigma_costau

static
create_gas_oil
(params=None)[source]¶ Create a GasOil object from a dictionary of parameters.
Parameterization (Corey/LET) is inferred from presence of certain parameters in the dictionary.
Don’t rely on behaviour of you supply both Corey and LET at the same time.
NB: the add_LET_* methods have the names ‘l’, ‘e’ and ‘t’ in their signatures, which is not precise enough in this context, so we require e.g. ‘Lg’ and ‘Log’ (which both will be translated to ‘l’). Also note that in this factory context, kroend is an ambiguous parametre, krogend must be used.
 Recognized parameters:
swirr, sgcr, “sorg, swl, krgendanchor, h, tag, ng, krgend, krgmax, nog, krogend, lg, eg, tg, log, eog, tog

static
create_water_oil_gas
(params=None)[source]¶ Create a WaterOilGas object from a dictionary of parameters
Parameterization (Corey/LET) is inferred from presence of certain parameters in the dictionary.
Check create_water_oil() and create_gas_oil() for lists of supported parameters (case insensitive)

static
create_scal_recommendation
(params, tag='', h=None)[source]¶ Set up a SCAL recommendation curve set from input as a dictionary of dictionary.
The keys in in the dictionary must be “low”, “base” and “high”.
The value for “low” must be a new dictionary with saturation endpoints and LET/Corey parameters, as you would feed it to the create_water_oil_gas() factory function;
 Recognized parameters:
Lw, Ew, Tw, Low, Eow, Tow, Lg, Eg, Tg, Log, Eog, Tog, nw, now, ng, nog, swirr, swl, sorw, sorg, sgcr
For oilwater only, you may omit the LET parameters for gas and oilgas

static
pyscal.gasoil module¶
Representing a GasOil object

class
pyscal.gasoil.
GasOil
(swirr=0, sgcr=0.0, h=0.01, swl=0.0, sorg=0.0, tag='', krgendanchor='sorg', fast=False)[source]¶ Bases:
object
Object to represent twophase properties for gas and oil.
Parametrizations available for relative permeability:
Corey
LET
or data can alternatively be read in from tabulated data (as Pandas DataFrame).
No support (yet) to add capillary pressure.
krgend can be anchored both to 1swlsorg and to 1swl. Default is to anchor to 1swlsorg. If the krgendanchor argument is something else than the string sorg, it will be anchored to 1swl.
Code duplication warning: Code is analogous to WaterOil, but with some subtle details sufficiently different for now warranting its own code (no easy inheritance)
 Parameters
swirr (float) – Absolute minimal water saturation at infinite capillary pressure. Not in use currently, except for in informational headers and for consistency checks.
swl (float) – First water saturation point in water tables. In GasOil, it is used to obtain the normalized oil and gas saturation.
sgcr (float) – Critical gas saturation. Gas will not be mobile before the gas saturation is above this value.
sorg (float) – Residual oil saturation after gas flooding. At this oil saturation, the oil has zero relative permeability.
krgendanchor (str) – Set to sorg or something else, where to anchor krgend. If sorg, then the normalized gas saturation will be equal to 1 at 1  swl  sgcr  sorg, if not, it will be 1 at 1  swl  sgcr. If sorg is zero it does not matter.
h (float) – Saturation steplength in the outputted table.
tag (str) – Optional string identifier, only used in comments.
fast (bool) – Set to True if in order to skip some integrity checks and nicetohave features. Not needed to set for normal pyscal runs, as speed is seldom crucial. Default False

add_fromtable
(dframe, sgcolname='Sg', krgcolname='krg', krogcolname='krog', pccolname='pcog', krgcomment='', krogcomment='', pccomment='')[source]¶ Interpolate relpermdata from a dataframe.
The saturation range with endpoints must be set up beforehand, and must be compatible with the tabular input. The tabular input will be interpolated to the initialized Sgtable.
If you have krg and krog in different dataframes, call this function twice
Calling function is responsible for checking if any data was actually added to the table.

set_endpoints_linearpart_krg
(krgend, krgmax=None)[source]¶ Set linear parts of krg outside endpoints.
Curve will be linear from [1  swl  sorg, 1  swl] (from krgend to krgmax) and zero in [0, sgcr]. Except special handling for krgendanchor:
If krgendanchor is set to sorg (default), then the normalized gas saturation sgn (which is what is raised to the power of ng) is 1 at 1  swl  sgcr  sorg. If not, it is 1 at 1  swl  sgcr.
krgmax is only relevant if krgendanchor is ‘sorg’
This function is used by add_corey/LET_gas(), and perhaps by other utility functions. It should not be necessary for endusers.
 Parameters
krgend (float) – krg at 1  swl  sgcr  sorg. Checkme.
krgmax (float) – krg at Sg=1swl. Default 1.

set_endpoints_linearpart_krog
(kroend, kromax)[source]¶ Set linear parts of krog outside endpoints.
Zero for sg above 1  sorg  swl.
Linear from kromax to kroend from sg in [0, sgcr]
This function is used by add_corey/LET_oil(), and perhaps by other utility functions. It should not be necessary for endusers.
 Parameters
kroend (float) – krog at sg=sgcr
kromax (float) – krog at Sg=0. Default 1.

add_corey_gas
(ng=2, krgend=1, krgmax=None)[source]¶ Add krg data through the Corey parametrization
A column called ‘krg’ will be added. If it exists, it will be replaced.
If krgendanchor is set to sorg (default), then the normalized gas saturation sgn (which is what is raised to the power of ng) is 1 at 1  swl  sgcr  sorg. If not, it is 1 at 1  swl  sgcr.
krgmax is only relevant if krgendanchor is ‘sorg’

add_corey_oil
(nog=2, kroend=1, kromax=None)[source]¶ Add kro data through the Corey parametrization
A column named ‘kro’ will be added to the internal DataFrame, replaced if it exists.
All values above 1  sorg  swl are set to zero.
kromax is ignored if sgcr is close to zero
 Parameters
nog (float) – Corey exponent for oil
kroend (float) – Value for krog at normalized oil saturation 1
kromax (float) – Value for krog at gas saturation 0.
 Returns
None (modifies internal class state)

add_LET_gas
(l=2, e=2, t=2, krgend=1, krgmax=None)[source]¶ Add gas relative permability data through the LET parametrization
A column called ‘krg’ will be added, replaced if it does not exist
If krgendanchor is set to sorg (default), then the normalized gas saturation sgn (which is what is raised to the power of ng) is 1 at 1  swl  sgcr  sorg. If not, it is 1 at 1  swl  sgcr
 Parameters
l (float) – L parameter in LET
e (float) – E parameter in LET
t (float) – T parameter in LET
krgend (float) – Value of krg at normalized gas saturation 1
krgmax (float) – Value of krg at gas saturation 1
 Returns
None (modifies internal state)

add_LET_oil
(l=2, e=2, t=2, kroend=1, kromax=None)[source]¶ Add oil (vs gas) relative permeability data through the Corey parametrization.
A column named ‘krog’ will be added, replaced if it exists.
All values where sg > 1  sorg  swl are set to zero.
kromax is ignored if sgcr is close to zero
 Parameters
l (float) – L parameter
e (float) – E parameter
t (float) – T parameter
kroend (float) – The value at gas saturation sgcr
kromax (float) – The value at gas saturation equal to 0.

estimate_sorg
()[source]¶ Estimate sorg of the current krg or krog data.
sorg is estimated by searching for a linear part in krg downwards from sg=1swl. In practice it is impossible to infer sorg = 0, since we are limited by h, and the last segment from sg=1swlh to sg=1swl can always be assumed linear.
If krgend is anchored to sorg, krg data is used to infer sorg. If not, krg cannot be used for this, and krog is used. sorg might be overestimated when krog is used if it very close to zero before reaching sorw.
If the curve is linear everywhere, sorg will be returned as sgcr + h
 Parameters
None –
 Returns
The estimated sorg.
 Return type
float

estimate_sgcr
(curve='krog')[source]¶ Estimate sgcr of the current krog data.
sgcr is estimated by searching for a linear part in krog upwards from sg=0. In practice it is impossible to infer sgcr = 0, since we are limited by h, and we always have to assume that the first segment is linear.
If the curve is linear everywhere, sgcr will be returned as the right endpoint.
 Parameters
curve (str) – Column name to use for search for linearity. Default is krog, if all of that is linear, you may try krg instead.
 Returns
The estimated sgcr.
 Return type
float

crosspoint
()[source]¶ Locate and return the saturation point where krg = krog
Accuracy of this crosspoint depends on the resolution chosen when initializing the saturation range (it uses linear interpolation to solve for the zero)
Warning: Code duplication from WaterOil, with column names changed only

selfcheck
()[source]¶ Check validities of the data in the table.
This is to catch errors that are either physically wrong or at least causes Eclipse 100 to stop.
Returns True if no errors are found, False if at least one is found.
If you call SGOF/SLGOF, this function must not return False.

SGOF
(header=True, dataincommentrow=True)[source]¶ Produce SGOF input for Eclipse reservoir simulator.
The columns sg, krg, krog and pc are outputted and formatted accordingly.
Metainformation for the tabulated data are printed as Eclipse comments.
 Parameters
header (bool) – Whether the SGOF string should be emitted. If you have multiple satnums, you should have True only for the first (or False for all, and emit the SGOF yourself). Defaults to True.
dataincommentrow (bool) – Whether metadata should be printed, defaults to True.

slgof_df
()[source]¶ Slice out an SLGOF table.
This is a used by the SLGOF() function, it is extracted as a single function to facilitate testing.

SLGOF
(header=True, dataincommentrow=True)[source]¶ Produce SLGOF input for Eclipse reservoir simulator.
The columns sl (liquid saturation), krg, krog and pc are outputted and formatted accordingly.
Metainformation for the tabulated data are printed as Eclipse comments.
 Parameters
header – boolean for whether the SLGOF string should be emitted. If you have multiple satnums, you should have True only for the first (or False for all, and emit the SGOF yourself). Defaults to True.
dataincommentrow – boolean for wheter metadata should be printed, defaults to True.

SGFN
(header=True, dataincommentrow=True)[source]¶ Produce SGFN input for Eclipse reservoir simulator.
The columns sg, krg, and pc are outputted and formatted accordingly.
Metainformation for the tabulated data are printed as Eclipse comments.
 Parameters
header – boolean for whether the SGOF string should be emitted. If you have multiple satnums, you should have True only for the first (or False for all, and emit the SGOF yourself). Defaults to True.
dataincommentrow – boolean for wheter metadata should be printed, defaults to True.

GOTABLE
(header=True, dataincommentrow=True)[source]¶ Produce GOTABLE input for the Nexus reservoir simulator.
The columns sg, krg, krog and pc are outputted and formatted accordingly.
Metainformation for the tabulated data are printed as Eclipse comments.
 Parameters
header – boolean for whether the SGOF string should be emitted. If you have multiple satnums, you should have True only for the first (or False for all, and emit the SGOF yourself). Defaults to True.
dataincommentrow – boolean for wheter metadata should be printed, defaults to True.
pyscal.scalrecommendation module¶
SCALrecommendation, container for low, base and high WaterOilGas objects

class
pyscal.scalrecommendation.
SCALrecommendation
(low, base, high, tag='', h=0.01)[source]¶ Bases:
object
A SCAL recommendation consists of three OilWaterGas objects, tagged low, base and high.
This container exists in order to to interpolation from 1 (low), through 0 (base) and to 1 (high).
 Parameters
low (WaterOilGas) – An object representing the low case
base (WaterOilGas) – An object representing the base case
high (WaterOilGas) – An object representing the high case
tag (str) – A string that describes the recommendation. Optional.

add_simple_J
(a=5, b=1.5, poro_ref=0.25, perm_ref=100, drho=300, g=9.81)[source]¶ Add (identical) simplified Jfunction to all wateroil curves in the SCAL recommendation set

interpolate
(parameter, parameter2=None, h=0.02)[source]¶ Interpolate between low, base and high parameter = 1 reproduces low curve parameter = 0 reproduces base curve parameter = 1 reproduces high curve
Endpoints are located for input curves, and interpolated individually. Interpolation for the nonlinear part is done on a normalized interval between the endpoints
Interpolation is linear in relpermdirection, and will thus not be linear in logrelpermdirection
This method returns an WaterOilGasTable object which can be realized into printed tables. No attempt is made to parametrize the interpolant in L,E,T parameter space, or Coreyspace.
If a second parameter is supplied (“parameter2”) this is used for the gasoil interpolation. This enables the gasoil interpolant to be fully uncorrelated to the wateroil interpolant. CHECK how this affects endpoints and Eclipse consistency!!
pyscal.utils module¶
Utility function for pyscal

pyscal.utils.
estimate_diffjumppoint
(table, xcol=None, ycol=None, side='right')[source]¶ Estimate the point where the ydata jumps from being linear in x to being nonlinear, or where it shift from one linear domain to another (for a piecewise linear function)
If xcol is sw, and ycol is krw, and side is ‘right’, this will typically estimate sorw for you. If side is ‘left’ it will give you swcr.
 Parameters
table (pd.DataFrame) – A Dataframe with x and y data
xcol (string) – The name of the column in table containing xdata. If None (default) the first column in table will be used.
ycol (string) – The name of the column in table containing ydata. If None (default) the second column in the table will be used.
side (string) – Must be ‘left’ or ‘right’. Decides whether to look from the right side of the xinterval or from the left side for the linear domain.
 Returns
The x value where the startlinear domain ends.
 Return type
float

pyscal.utils.
normalize_nonlinpart_wo
(curve)[source]¶ Make krw and krow functions that evaluate only on the (potentially) nonlinear part of the relperm curves, and with a normalized argument (0,1) on that interval.
For a WaterOil krw curve, the nonlinear part is from swcr to sorw. swcr is mapped to zero, and 1  sorw is mapped to 1. Then there is an assumed linear part from sorw to 1 which we ignore here.
For a WaterOil krow curve, the nonlinear part is from 1  sorw (mapped to zero) to swcr (mapped to 1). If swcr > swl, there is a linear part from swcr down to swl, ignored here.
These endpoints must be known the the WaterOil object coming in (the object can determine them using functions ‘estimate_sorw()’ and ‘estimate_swcr()’
If the entire curve is linear, it will not matter for this function, because this function only deals with the presumably known endpoints.
 Parameters
curve (WaterOil) – incoming oilwater curve set (krw and krow)
 Returns
 tuple of lambda functions. The first will evaluate krw on
the normalized Sw interval [0,1], the second will evaluate krow on the normalized So interval [0,1].

pyscal.utils.
normalize_nonlinpart_go
(curve)[source]¶ Make krg and krog functions that evaluates only on the (potentially) nonlinear part of the relperm curves, and with a normalized argument (0,1) on that interval.
For a GasOil krw curve, the nonlinear part is from sgcr to sorg. sgcr is mapped to sg=zero, and sg=1  sorg  swl is mapped to 1. Then there is an assumed linear part from sorg to 1 which we ignore here.
For a GasOil krow curve, the nonlinear part is from 1  sorg (mapped to zero) to sgcr (mapped to 1).
These endpoints must be known the the GasOil object coming in (the object can determine them using functions ‘estimate_sorg()’ and ‘estimate_sgcr()’
If the entire curve is linear, it will not matter for this function, because this function only deals with the presumably known endpoints.
 Parameters
curve (GasOil) – incoming gasoil curve set (krg and krog)
 Returns
 tuple of lambda functions. The first will evaluate krg on
the normalized Sg interval [0,1], the second will evaluate krog on the normalized So interval [0,1].

pyscal.utils.
normalize_pc
(curve)[source]¶ Normalize the capillary pressure curve.
This is only normalized with respect to the smallest and largest saturation present in the table, not to the couldbeuncertain swirr that the object could contain, because we then have to make assumptions on the equations used to generate the data in the table.

pyscal.utils.
interpolate_wo
(wo_low, wo_high, parameter, h=0.01)[source]¶ Interpolates between two wateroil 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.
 Parameters
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 stepsize in interpolant. If defaulted, a value smaller than in the input curves are used, to preserve information.
 Returns
A new oilwater curve

pyscal.utils.
interpolate_go
(go_low, go_high, parameter, h=0.01)[source]¶ Interpolates between two gasoil curves.
The saturation endpoints for the curves must be known by the objects. They can be estimated by estimate_sorg() 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.
 Parameters
go_low (GasOil) – a “low” case
go_high (GasOil) – 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 stepsize in interpolant. If defaulted, a value smaller than in the input curves are used, to preserve information.
 Returns
A new gasoil curve

pyscal.utils.
interpolator
(tableobject, wo_low, wo_high, parameter, sat='sw', kr1='krw', kr2='krow', pc='pc')[source]¶ Interpolates between two curves.
DEPRECATED FUNCTION!
The interpolation parameter is 0 through 1, irrespective of phases or lowbase/basehigh/lowhigh.
 Parameters
tabjeobject (WaterOil or GasOil) – A partially setup object where relperm and pc columns are to be filled with numbers.
wo_low (WaterOil or GasOil) – “Low” case of interpolation (relates to interpolation parameter 0). Must be copies, as they will be modified.
wo_high – Ditto, relates to interpolation parameter 1
parameter (float) – Between 0 and 1, what you want to interpolate to.
sat (str) – Name of the saturation column, typically ‘sw’ or ‘sg’
kr1 (str) – Name of the first relperm column (‘krw’ or ‘krg’)
kr2 (str) – Name of the second relperm column (‘krow’ or ‘krog’)
pc (str) – Name of the capillary pressure column (‘pc’)
 Returns
None, but modifies the first argument.
pyscal.wateroil module¶
Wateroil module

class
pyscal.wateroil.
WaterOil
(swirr=0.0, swl=0.0, swcr=0.0, sorw=0.0, h=0.01, tag='', fast=False)[source]¶ Bases:
object
A representation of twophase properties for oilwater.
Can hold relative permeability data, and capillary pressure.
 Parametrizations for relative permeability:
Corey
LET
 For capillary pressure:
Simplified Jfunction
For object initialization, only saturation endpoints must be inputted, and saturation resolution. An optional string can be added as a ‘tag’ that can be used when outputting.
Relative permeability and/or capillary pressure can be added through parametrizations, or from a dataframe (will incur interpolation).
Can be dumped as include files for Eclipse/OPM and Nexus simulators.
 Parameters
swirr (float) – Absolute minimal water saturation at infinite capillary pressure.
swl (float) – First water saturation point in generated table. Used for normalized saturations.
swcr (float) – Critical water saturation. Water will not be mobile before the water saturation is above this value.
sorw (float) – Residual oil saturation after water flooding. At this oil saturation, the oil has zero relative permeability.
h (float) – Saturation steplength in the outputted table.
tag (str) – Optional string identifier, only used in comments.
fast (bool) – Set to True if in order to skip some integrity checks and nicetohave features. Not needed to set for normal pyscal runs, as speed is seldom crucial. Default False

add_fromtable
(dframe, swcolname='Sw', krwcolname='krw', krowcolname='krow', pccolname='pcow', krwcomment='', krowcomment='', pccomment='', sorw=None)[source]¶ Interpolate relpermdata from a dataframe.
The saturation range with endpoints must be set up beforehand, and must be compatible with the tabular input. The tabular input will be interpolated to the initialized Swtable
If you have krw and krow in different dataframes, call this function twice
Calling function is responsible for checking if any data was actually added to the table.
The relpermdata will be interpolated using a monotone cubic interpolator below 1sorw, and linearly above 1sorw. Capillary pressure data will be interpolated monotone cubicly over the entire saturation interval
The python package ecl2df has a tool for converting Eclipse input files to dataframes.
 Parameters
dframe (pd.DataFrame) – containing data
swcolname (string) – column name with the saturation data in the dataframe df
krwcolname (string) – name of column in df with krw
krowcolname (string) – name of column in df with krow
pccolname (string) – name of column in df with capillary pressure data
krwcomment (string) – Inserted into comment
krowcomment (string) – Inserted into comment
pccomment (str) – Inserted into comment
sorw (float) – Explicit sorw. If None, it will be estimated from the numbers in krw (or krow)

add_corey_water
(nw=2, krwend=1, krwmax=None)[source]¶ Add krw data through the Corey parametrization
A column named ‘krw’ will be added. If it exists, it will be replaced.
It is assumed that there are no sw points between sw=1sorw and sw=1, which should give linear interpolations in simulators. The corey parameter applies up to 1sorw.
krwmax will be ignored if sorw is close to zero
 Parameters
nw (float) – Corey parameter for water.
krwend (float) – value of krw at 1  sorw.
krwmax (float) – maximal value at Sw=1. Default 1

set_endpoints_linearpart_krw
(krwend, krwmax=None)[source]¶ Set linear parts of krw outside endpoints.
Curve will be linear from [1  sorw, 1] (from krwmax to krwend) and zero in [swl, swcr]
This function is used by add_corey_water(), and perhaps by other utility functions. It should not be necessary for endusers.
 Parameters
krwend (float) – krw at 1  sorwr
krwmax (float) – krw at Sw=1. Default 1.

set_endpoints_linearpart_krow
(kroend, kromax=None)[source]¶ Set linear parts of krow outside endpoints
Curve will be linear in [swl, swcr] (from kromax to kroend) and zero in [1  sorw, 1]
This function is used by add_corey_water(), and perhaps by other utility functions. It should not be necessary for endusers.
 Parameters
kroend (float) – value of kro at swcr
kromax (float) – maximal value of kro at sw=swl. Default 1

add_LET_water
(l=2, e=2, t=2, krwend=1, krwmax=None)[source]¶ Add krw data through LET parametrization
It is assumed that there are no sw points between sw=1sorw and sw=1, which should give linear interpolations in simulators. The LET parameters apply up to 1sorw.
krwmax will be ignored if sorw is close to zero.
 Parameters
l (float) – LET parameter
e (float) – LET parameter
t (float) – LET parameter
krwend (float) – value of krw at 1  sorw
krwmax (float) – maximal value at Sw=1. Default 1

add_LET_oil
(l=2, e=2, t=2, kroend=1, kromax=None)[source]¶ Add kro data through LET parametrization
kromax will be ignored if swcr is close to swl.
 Parameters
l (float) – LET parameter
e (float) – LET parameter
t (float) – LET parameter
kroend (float) – value of kro at swcr
kromax (float) – maximal value of kro at sw=swl. Default 1
 Returns
None (modifies object)

add_corey_oil
(now=2, kroend=1, kromax=None)[source]¶ Add kro data through the Corey parametrization
Corey applies to the interval between swcr and 1  sorw
Curve is linear between swl and swcr, zero above 1  sorw.
kromax will be ignored if swcr is close to swl.
 Parameters
now (float) – Corey exponent
kroend (float) – kro value at swcr
kromax (float) – kro value at swl
 Returns
None (modifies object)

add_simple_J
(a=5, b=1.5, poro_ref=0.25, perm_ref=100, drho=300, g=9.81)[source]¶ Add capillary pressure function from a simplified Jfunction
This is the ‘inverse’ or ‘RMS’ version of the a and b, the formula is
J = a S_w^b
J is not dimensionless. Doc: https://wiki.equinor.com/wiki/index.php/Res:Water_saturation_from_Leverett_Jfunction
poro_ref is a fraction, between 0 and 1 perm_ref is in milliDarcy drho has SI units kg/m³. Default value is 300 g has SI units m/s², default value is 9.81

add_normalized_J
(a, b, poro, perm, sigma_costau)[source]¶ Add capillary pressure in bar through a normalized Jfunction.
\[p_c = \frac{\left(\frac{S_w}{a}\right)^{\frac{1}{b}} \sigma \cos \tau}{\sqrt{\frac{k}{\phi}}}\]The Sw saturation used in the formula is normalized with respect to the swirr parameter.
 Parameters
a (float) – a parameter
b (float) – b exponent (typically negative)
poro (float) – Porosity value, fraction between 0 and 1
perm (float) – Permeability value in mD
sigma_costau (float) – Interfacial tension in mN/m (typical value 30 mN/m)
 Returns
None. Modifies pc column in self.table, using bar as pressure unit.

add_skjaeveland_pc
(cw, co, aw, ao, swr=None, sor=None)[source]¶ Add capillary pressure from the Skjæveland correlation,
Doc: https://wiki.equinor.com/wiki/index.php/Res:The_Skjaeveland_correlation_for_capillary_pressure
The implementation is unit independent, units are contained in the input constants.
If swr and sor are not provided, it will be taken from the swirr and sorw. Only use different values here if you know what you are doing.
Modifies or adds self.table.pc if succesful. Returns false if error occured.

add_LET_pc_pd
(Lp, Ep, Tp, Lt, Et, Tt, Pcmax, Pct)[source]¶ Add a primary drainage LET capillary pressure curve.
Docs: https://wiki.equinor.com/wiki/index.php/Res:The_LET_correlation_for_capillary_pressure
Note that Pc where Sw > 1  sorw will appear linear because there are no saturation points in that interval.

add_LET_pc_imb
(Ls, Es, Ts, Lf, Ef, Tf, Pcmax, Pcmin, Pct)[source]¶ Add an imbition LET capillary pressure curve.
Docs: https://wiki.equinor.com/wiki/index.php/Res:The_LET_correlation_for_capillary_pressure

estimate_sorw
(curve='krw')[source]¶ Estimate sorw of the current krw data.
This is mostly relevant when add_fromtable() has been used. sorw is estimated by searching for a linear part in krw downwards from sw=1. In practice it is impossible to infer sorw = 0, since we are limited by h, and the last segment from sw=1h to sw=1 can always be assumed linear. Expect sorw = h if the real sorw = 0, but do not depend that it might not return zero in the future (one could argue that sorw = h should be specially treated to mean sorw = 0)
If the curve is linear everywhere, sorw will be returned as swl + h
krow is not used, and should probably not be, as it can be very close to zero before approaching sorw.
 Parameters
curve (str) – Colum name of column to use, default is krw. If this is all linear, but krow is not, you might be better off with krow
 Returns
The estimated sorw.
 Return type
float

estimate_swcr
(curve='krow')[source]¶ Estimate swcr of the current krw data.
swcr is estimated by searching for a linear part in krw upwards from sw=swl. In practice it is impossible to infer swcr = 0, since we are limited by h, and the first segment is assumed linear anyways.
If the curve is linear everywhere, swcr can end up at the right end of your saturation interval.
 Parameters
curve (str) – Colum name of column to use, default is krow. If this is all linear, but krw is not, you might be better off with krw
 Returns
The estimated sgcr.
 Return type
float

crosspoint
()[source]¶ Locate and return the saturation point where krw = krow
Accuracy of this crosspoint depends on the resolution chosen when initializing the saturation range

selfcheck
()[source]¶ Check validities of the data in the table.
An unfinished object will return False.
If you call SWOF, this function must not return False
This function should not throw an exception, but capture the error and give an error.

SWOF
(header=True, dataincommentrow=True)[source]¶ Produce SWOF input for Eclipse reservoir simulator.
The columns sw, krw, krow and pc are outputted and formatted accordingly.
Metainformation for the tabulated data are printed as Eclipse comments.
 Parameters
header (bool) – Indicate whether the SWOF string should be emitted. If you have multiple SATNUMs, you should set this to True only for the first (or False for all, and emit the SWOF yourself). Default True
dataincommentrow (bool) – Wheter metadata should be printed. Defualt True
pyscal.wateroilgas module¶
Container object for one WaterOil and one GasOil object

class
pyscal.wateroilgas.
WaterOilGas
(swirr=0, swl=0.0, swcr=0.0, sorw=0.0, sorg=0, sgcr=0, h=0.01, tag='', fast=False)[source]¶ Bases:
object
A representation of threephase properties for oilwatergas
Use one object for each satnum.
One WaterOil and one GasOil object will be created, with compatible saturation ranges. Access the class members ‘wateroil’ and ‘gasoil’ directly to add curves.
All arguments can be defaulted, and all are zero except h.
 Parameters
swirr (float) – Irreducible water saturation for capillary pressure
swl (float) – First water saturation point in outputted tables.
swcr (float) – Critical water saturation, water is immobile below this
sorw (float) – Residual oil saturation
sgcr (float) – Critical gas saturation, gas is immobile below this
h (float) – Saturation intervals in generated tables.
tag (str) – Optional text that will be included as comments.
fast (bool) – Set to True if you prefer speed over robustness. Not recommended, pyscal will not guarantee valid output in this mode.

SWOF
(header=True, dataincommentrow=True)[source]¶ Return a SWOF string. Delegated to the wateroil object

SGOF
(header=True, dataincommentrow=True)[source]¶ Return a SGOF string. Delegated to the gasoil object.

SLGOF
(header=True, dataincommentrow=True)[source]¶ Return a SLGOF string. Delegated to the gasoil object.

SGFN
(header=True, dataincommentrow=True)[source]¶ Return a SGFN string. Delegated to the gasoil object.

SWFN
(header=True, dataincommentrow=True)[source]¶ Return a SWFN string. Delegated to the wateroil object.

SOF3
(header=True, dataincommentrow=True)[source]¶ Return a SOF3 string, combining data from the wateroil and gasoil objects.
So  the oil saturation ranges from 0 to 1swl. The saturation points from the WaterOil object is used to generate these
Module contents¶
A module for creating relative permeability input curves for Eclipse and Nexus.