SOSAT package
Module contents
The State of Stress Analysis Tool (SOSAT) is a Python package that helps analyze the state of stress in the subsurface using various types of commonly available characterization data such as well logs, well test data such as leakoff and minifrac tests, regional geologic information, and constraints on the state of stress imposed by the existence of faults and fractures with limited frictional shear strength. It employs a Bayesian approach to integrate these data into a probability density function for the principal stress components.
Submodules
SOSAT.stress_state module
- class SOSAT.stress_state.StressState(depth, avg_overburden_density, pore_pressure, depth_unit='m', density_unit='kg/m^3', pressure_unit='MPa', min_stress_ratio=0.4, max_stress_ratio=3.25, nbins=200, stress_unit='MPa')[source]
Bases:
objectA class to contain all data necessary to define the probability distribution for all possible stress states at a given point in the subsurface.
- depthfloat
The true vertical depth of the point being analyzed
- vertical_stressfloat
The total vertical stress, currently taken as deterministic
- pore_pressurefloat
The pore pressure, currently taken as deterministic
- shmin_gridnumpy MaskedArray object
A 2D array containing the value of the minimum horizontal stress for each stress state considered. Values that are not admissible, such as where the minimum horizontal stress would be greater than the maximum horizontal stress are masked
- shmax_gridnumpy MaskedArray object
A 2D array containing the value of the mmaximum horizontal stress for each stress state considered. Values that are not admissible, such as where the minimum horizontal stress would be greater than the maximum horizontal stress are masked
- stress_unitstr
The unit used for stress
- depth_unitstr
The unit used for vertical depth
- depthfloat
the true vertical depth of the point being analyzed
- average_overburden_densityfloat
average mass density of all overlying formations
- pore_pressurefloat
formation pore pressure
- depth_unitstr, optional
unit of measurement for depth, see list of units in pint package documentation
- density_unitstr, optional
unit of measurement for mass density, see list of units in pintpackage documentation
- pressure_unitstr, optional
unit of measurement for pressure, see list of units in pint package documentation
- min_stress_ratiofloat, optional
Minimum stress included in the analysis expressed as a fraction of the vertical stress. This is not intended as a way to express a prior probability but is instead meant as a convenient way to set the bounds of stress considered in the analysis. It does effectively truncate the stress distribution at this value and so should be chose well outside of the zone of significant probability density. Default value is 0.4
- max_stress_ratiofloat
Maximum stress included in the analysis expressed as a fraction of the vertical stress. This is not intended as a way to express a prior probability but is instead meant as a convenient way to set the bounds of stress considered in the analysis. It does effectively truncate the stress distribution at this value and so should be chose well outside of the zone of significant probability density. Default value is 3.25
- nbinsint
number of bins to use for the horizontal principal stresses. The same number is used for both horizontal principal stresses. Default value is 200.
This class applies the Bayesian approach to quantifying uncertainty in the state of stress at a single point in the subsurface that is outlined in [1]_. By “single point” here we mean any volume of the subsurface that the user wishes to treat as having a homogeneous stress state the. Depending on the application this could be a volume with length scale of a log scale (tens of centimeters) or in a regional-scale analysis could be a volume with length scale of kilometers.
Currently the vertical stress and pore pressure are taken as deterministically known, so that uncertainties in these values are not reflected in the uncertainty in the the horizontal principal stresses. This may change in a future release, but in many applications is not a big limitation because there is generally a smaller uncertainty in the vertical stress and pore pressure compared to the horizontal principal stresses.
Currently this class does not contain stress orientation information, though this too is planned to change in a future release. Though this would only add significant value when methods to add different StressState objects are needed and implemented. This will be required, for example, to interpolate between different points where a StressState object has been parameterized.
[1] Burghardt, J. “Geomechanical Risk Assessment for Subsurface Fluid Disposal Operations,” Rock Mech Rock Eng 51, 2265–2288 (2018) https://doi.org/10.1007/s00603-018-1409-1
To compute and plot the posterior distribution at a point with a frictional faulting constraint, you would do the following:
>>> from SOSAT import StressState >>> from SOSAT.constraints import FaultConstraint >>> ss = StressState(1.0, 2.5, 0.3, depth_unit='km', density_unit='g/cm^3', pressure_unit='MPa')
>>> sigv = ss.vertical_stress >>> fc = FaultConstraint() >>> ss.add_constraint(fc) >>> fig = ss.plot_posterior() >>> plt.savefig("fault_constraint_posterior.png")
- A_phi_calculate()[source]
Computes the scalar A_phi value for each stress state included in the class. The scalar regime parameter varies from 0 to 1. The scalar measure of the faulting regime is defined in Simpson (1997):
phi = (sigma2-sigma3)/ (sigma1-sigma3) n = 0, 1, and 2 respectively for normal, strike-slip, and reverse faulting regime respectively. A_phi = (n+0.5) + (-1)^n*(phi-0.5)
Using this definition, A_phi value ranges from 0 to 3, where [0,1] corresponds to normal faulting regime, [1,2] corresponds to strike-slip faulting regime, and [2,3] corresponds to reverse faulting regime.
- 2D Numpy MaskedArray with dtype=float
The array is square with dimensions
nbins
- add_constraint(constraint)[source]
Method to add a constraint to the stress state probability distribution. Constraints will be applied in the order that they are added
- constraintConstraint object
The object containing the information for the constraint, must be a class in the SOSAT.constraints submodule
- evaluate_posterior()[source]
Method to evaluate the posterior joint probability density given the constraints that have been added. If no constraints have been added the prior distribution will be returned.
- 2D Numpy MaskedArray with dtype=float
The array is square with dimensions
nbins, where each entry in the array contains the probability density for the stress state defined byshmin_gridandshmax_grid
The probability density will be properly normalized such that the the values of all bins in the distribution will sum to one. The prior distribution is homogeneous for all compressive stress states considered in the distribution. The stress states considered in the distribution are governed by the min_stress_ratio and max_stress_ratio passed into the constructor of this class.
The posterior distribution is computed by recursively applying Bayes’ law using the likelihood function provided by each constraint object that has been added to this class.
- get_shmax_confidence_intervals(confidence)[source]
return an upper and lower bound within a specified confidence interval. Confidence interval should be specified as a fraction so that, for example, a 95% confidence interval is expressed as confidence=0.95
- get_shmax_marginal()[source]
get the marginal probability distribution for the maximum principal stress
- get_shmax_marginal_cdf()[source]
get the marginal cumulative probability function for the maximum horizontal stress
- get_shmin_confidence_intervals(confidence)[source]
return an upper and lower bound within a specified confidence interval. Confidence interval should be specified as a fraction so that, for example, a 95% confidence interval is expressed as confidence=0.95
- get_shmin_marginal()[source]
get the marginal probability distribution for the minimum principal stress
- get_shmin_marginal_cdf()[source]
get the marginal cumulative probability function for the minimum horizontal stress
- plot_posterior(figwidth=5.0, figheight=3.5, contour_levels=5, cmap=<matplotlib.colors.LinearSegmentedColormap object>)[source]
Makes a contour plot of the joint probability distribution of the maximum and minimum horizontal stresses
- figwidthfloat, optional
the width of the figure in inches, defaults to 5 inches
- figheightfloat, optional
the height of the figure in inches, defaults to 5 inches
- contour_levelsint, optional
the number of contour levels desired in the plot
- cmapcolormap object, optional
a matplotlib colormap object to use to display the probability density. Default is matplotlib.pyplot.cm.Greys
matplotlib.pyplot.Figure object
The plot is generated with matplotlib.pyplot.contourf
- regime()[source]
Computes the scalar regime parameters for each stress state included in the class. The scalar regime parameter varies from negative one to one. It is defined the vector space where each each stress state is represented by a vector whose head lies at the coordinate (shmax,shmin) and whose tail lies at the spherical stress state where
shmax = shmin = vertical stress
The scalar measure of the faulting regime is defined by the dot product of the vector for the given stress state and the unit vector give by
shmax = shmin = - 1/sqrt(2)
Using this definition values of the regime parameter between -1 and -sqrt(2)/2 correspond to thrust faulting states, values between -sqrt(2)/2 and sqrt(2)/2 correspond to strike- slip states, and values between sqrt(2)/2 and +1 correspond to normal faulting states.
- 2D Numpy MaskedArray with dtype=float
The array is square with dimensions
nbins
- SOSAT.stress_state.units = <pint.registry.UnitRegistry object>
The stress_state module contains classes and functions that are used to represent and plot the joint probability distribution for the minimum and maximum horizontal stresses.
SOSAT.constraints
SOSAT.constraints.fault_constraint
- class SOSAT.constraints.fault_constraint.FaultConstraint(friction_dist=None)[source]
Bases:
SOSAT.constraints.constraint_base.StressConstraintA class used to constrain the state of stress by the existence of frictional fault and fractures.
- friction_distsubclass of scipy.stats.rv_continuous
The probability density function for the fault friction coefficient
- friction_distsubclass of scipy.stats.rv_continuous, optional
a probability distribution function from the fault friction coefficient. If not provided the default is a lognormal distribution with s=0.15 and scale=0.7 passed into scipy.stats.lognorm
- loglikelihood(ss)[source]
Computes the likelihood of each stress state
- ss: SOSAT.StressState object
StressState object containing the stress states over which the likelihood is to be evaluated
- Numpy MaskedArray
The returned object is a Numpy MaskedArray containing the likelihood for each stress ss. The returned array is masked identically to ss.shmin_grid
- SOSAT.constraints.fault_constraint.critical_friction(sig1, sig3, pp)[source]
A function that computes the critical friction coefficient that would induce slip for the given combination of minimum and maximum principal stress and pore pressure
- sig1float or array_like
The maximum (most compressive) principal stress. If sig1 is array_like then sig3 must be a scalar of type float
- sig3float or array_like
The minimum (least compressive) principal stress. If sig3 is array_like then sig1 must be a scalar of type float
- ppfloat
The pore pressure
- mu_cfloat or array_like
The critical friction coefficient. If either sig1 or sig3 are array_like then the result will be an array containing the critical friction coefficient for each entry in the array.
SOSAT.constraints.faulting_regime_constraint
- class SOSAT.constraints.faulting_regime_constraint.FaultingRegimeConstraint(regime_dist)[source]
Bases:
SOSAT.constraints.constraint_base.StressConstraintA class that constrains the state of stress based on knowledge or assumptions about the relative probability of the three Andersonian faulting regimes.
- regime_distsubclass of scipy.stats.rv_continuous
The probability density function for the scalar regime parameter. See StressState.regime for details on the definition of the scalar regime parameter. Usually the and instance of SU is provided to apply a uniform probability to each Andersonian faulting regime with logistic functions to smooth the transition between each regime. However, any subclass of scipy.stats.rv_continuous defined from -1.0 to 1.0 can be used.
- loglikelihood(ss)[source]
Abstract method that requires all derived classes to implement a funcction that computes the loglikelihood of the constraint for a the stress states passed in through the StressState parameter
- ss: SOSAT.StressState object
StressState object containing the stress states over which the likelihood is to be evaluated
- Numpy MaskedArray
The returned object is a Numpy MaskedArray containing the log likelihood for each stress ss. The returned array is masked identically to ss.shmin_grid
- class SOSAT.constraints.faulting_regime_constraint.SU_gen(momtype=1, a=None, b=None, xtol=1e-14, badvalue=None, name=None, longname=None, shapes=None, extradoc=None, seed=None)[source]
Bases:
scipy.stats._distn_infrastructure.rv_continuousA class used to generate smoothed semi-uniform probability distributions for the scalar regime parameter. Most commonly this is used to define a probability distribution for the three Andersonian faulting regimes. A logistic function is used to smooth the transition between the different faulting regimes.
- w_NFfloat
the weight assigned to stress states for which the scalar regime parameter is less than k2; with the default value of k2 this corresponds to normal faulting stress states; the absolute value only matters relative to the weight assigned to the other two faulting regimes
- w_SSfloat
the weight assigned to stress states for which the scalar regime parameter is between k1 and k2; with the default values of k1 and k2 this corresponds to strike-slip faulting stress states; the absolute value only matters relative to the weight assigned to the other two faulting regimes
- w_TFfloat
the weight assigned to stress states for which the scalar regime parameter is greater than k1; with the default value of k1 this corresponds to thrust faulting stress states; the absolute value only matters relative to the weight assigned to the other two faulting regimes
- theta1float, optional
the first cutoff angle; defaults to a value of sqrt(2)/2, which is the value of the scalar regime parameter that marks the transition from thrust faulting to strike-slip faulting regimes
- k1float, optional
a parameter controlling the width of the sigmoid transition at theta1. Larger numbers yield a more gradual transition. Default value is 300
- theta2float
the second cutoff angle; default value is -sqrt(2)/2, which is the value of the scalar regime parameter that makrs the transition from strike-slip faulting to normal faulting.
- k2foat, opptional
a parameter controlling the width of the sigmoid transition at theta2. Larger numbers yield a more gradual transition. Default value is 300
The methods of scipy.stats.rv_continuous that are overridden are private methods. The corresponding public methods check their arguments before calling the private methods.
SOSAT.constraints.breakout_constraint
- class SOSAT.constraints.breakout_constraint.BreakoutConstraint(breakout_exists, UCS_dist, rock_friction_angle_dist, rock_friction_angle_units, mud_pressure_dist, mud_temperature_dist, formation_temperature, YM, PR, CTE, pressure_unit='Pa')[source]
Bases:
SOSAT.constraints.constraint_base.StressConstraintA class used to constrain the stress state by the existence or non existence of borehole breakouts at the location being analyzed. If breakouts exists that generally indicates that the maximum horizontal stress is much larger than the minimum horizontal stress, if not breakout exists that puts a limit on how large the maximum horizontal stress could be; the magnitude of that limit depends on the strength of the rock, drilling mud weight, temperature, etc. Significant uncertainty in these parameters, especially the rock strength and mud weight makes the constraint provided by a breakout analysis much weaker. This class seeks to account for these uncertainties in the posterior stress distribution
No public attributes
- breakout_existsbool
Indication whether or not breakouts exist
- UCS_distsubclass of scipy.stats.rv_continuous
A probability distribution for the unconfined compressive strength. Shoudl use the same pressure unit as is used by the mud pressure and Young’s modulus, but this can be any unit as specified though the optional pressure_unit parameter; this shoudl be an estimate for the minimum UCS in the zone of interest since that is what would govern the formation of breakouts, not the average or representative value
- rock_friction_angle_distsubclass of scipy.stats.rv_continuous
A probabiilty distribution for the rock friction angle.
- rock_friction_angle_unitsstr
The unit used for the rock friction angle. Should be an angular unit recognized by pint.UnitRegistry (i.e. ‘deg’ for degrees, ‘radians’ for radians
- mud_pressure_distsubclass of scipy.stats.rv_continuous
The probability distribution for the minimum mud pressure experienced by the relevant section of borehole from the time that the well was drilled until the log used to identify the presence or absence of breakouts was run; mud pressure should be specified in the same pressure unit as is used for UCS and Young’s modulus, but this can be any unit as specified though the optional pressure_unit parameter, which defaults to ‘Pa’; conversion from mud weight must be performed by the user of this class
- mud_temperature_distsubclass of scipy.stats.rv_continuous
The probability distribution for the maximum mud temperature; the maximum value is of interest rather than the average value since the formation of a breakout is governed by the maximum value only
- formation_temperaturefloat
Formation temperature, which is taken as deterministic since it is usually not highly uncertain
- YMfloat
Formation Young’s Modulus, which is taken as deterministic since the formation of breakouts is only weakly dependent on this parameter; should be specified in the same pressure unit as is used for mud pressure and Young’s modulus, but this can be any unit as specified though the optional pressure_unit parameter, which defaults to ‘Pa’
- PRfloat
Formation Poisson’s Ratio, which is taken as deterministic since the formation of breakouts is only weakly dependent on this parameter
- CTEfloat
Formation coefficient of thermal expansion, which is taken as deterministic since the formation of breakouts is only weakly dependent on this parameter
- pressure_unitstr, optional
The unit used for UCS and Young’s modulus; should be a unit recognized by pint.UnitRegistry; defaults to ‘Pa’
This class uses a Mohr Coulomb (MC) failure criterion to evaluate the probability of a breakout occuring. The Mohr Coulomb criterion uses two parameters, most often a friction angle and cohesion. In this class the unconfined compressive strength (UCS) and friction angle were chosen instead of the cohesion and friction angle. This is because the UCS is a more commonly known and intuitive property, and the cohesion MC parameter can be calculated given the UCS and friction angle.
While this class allows users to use any probability distribution that derives from the scipy.stats.rv_continuous class, users are cautioned against using any distribution that has finite probability density for negative parameter values, since negative strength values are not physically meaningful. Therefore, lognormal distributions are more appropriate than a normal distribution, for example.
- loglikelihood(ss)[source]
Computes the loglikelihood of each stress state given the presence or absence of breakouts, formation properties, and mud properties specified
- ss: SOSAT.StressState object
StressState object containing the stress states over which the likelihood is to be evaluated
- Numpy MaskedArray
The returned object is a Numpy MaskedArray containing the likelihood for each stress ss. The returned array is masked identically to ss.shmin_grid
- SOSAT.constraints.breakout_constraint.MCfail(sig1, sig3, phi, Co)[source]
Mohr Coulomb failure criterion
- sig1float, array_like
maximum principal stress
- sig3float, array_like
minimum principal stress
- phifloat
friction angle
- Cofloat
cohesion
- ffloat or array_like
The value of the failure function, which is defined so that negative values indicate no failure and positive values indicate failure, a zero value is at incipient failure
SOSAT.constraints.DITF_constraint
- class SOSAT.constraints.DITF_constraint.DITFConstraint(DITF_exists, mud_pressure_dist, mud_temperature_dist, tensile_strength_dist, formation_temperature, YM, PR, CTE, pressure_unit='Pa')[source]
Bases:
SOSAT.constraints.constraint_base.StressConstraintA class used to constrain the stress state by the existence or non existence of drilling-induced tensile fractures (DITF) at the location being analyzed. Depending on the mud and formation temperatures, mud weights, and rock strength and whether or not significant mud losses were observed, if DITF’s exist it generally indicates that the maximum horizontal stress is much larger than the minimum principal stress.
No public attributes
- DITF_existsbool
Indication whether or not DITF exist
- mud_pressure_distsubclass of scipy.stats.rv_continuous
The probability distribution for the maximum mud pressure experienced by the relevant section of borehole from the time that the well was drilled until the log used to identify the presence or absence of breakouts was run; mud pressure should be specified in the same pressure unit as is used for UCS and Young’s modulus, but this can be any unit as specified though the optional pressure_unit parameter, which defaults to ‘Pa’; conversion from mud weight must be performed by the user of this class
- mud_temperature_distsubclass of scipy.stats.rv_continuous
The probability distribution for the minimum mud temperature; the minimum value is of interest rather than the average value since the formation of a DITF is governed by the minimum value only
- tensile_strength_distsubclass of scipy.stats.rv_continuous
The probability distribution for minimum the minimum tensile strength in the zone being analyzed. DITFs will form at the weakest portion of the well for a given stress state, so whether they form or not is dependent on the minimum tensile strength rather than an average representative value
- formation_temperaturefloat
Formation temperature, which is taken as deterministic since it is usually not highly uncertain
- YMfloat
Formation Young’s Modulus, which is taken as deterministic since the formation of DITF is only weakly dependent on this parameter; should be specified in the same pressure unit as is used for mud pressure and Young’s modulus, but this can be any unit as specified though the optional pressure_unit parameter, which defaults to ‘Pa’
- PRfloat
Formation Poisson’s Ratio, which is taken as deterministic since the formation of DITFs is only weakly dependent on this parameter
- CTEfloat
Formation coefficient of thermal expansion, which is taken as deterministic since the formation of DITF is only weakly dependent on this parameter
- pressure_unitstr, optional
The unit used for UCS and Young’s modulus; should be a unit recognized by pint.UnitRegistry; defaults to ‘Pa’
While this class allows users to use any probability distribution that derives from the scipy.stats.rv_continuous class for the mud temperature, pressure, and formation tensile strength, users are cautioned against using any distribution that has finite probability density for negative parameter values, since negative strength values are not physically meaningful. Therefore, lognormal distributions are more appropriate than a normal distribution, for example.
- loglikelihood(ss)[source]
Computes the likelihood of each stress state given the presence or absence of DITFs, formation and mud properties specified.
- ss: SOSAT.StressState object
StressState object containing the stress states over which the likelihood is to be evaluated
- Numpy MaskedArray
The returned object is a Numpy MaskedArray containing the likelihood for each stress ss. The returned array is masked identically to ss.shmin_grid
SOSAT.constraints.stress_measurement_constraint
- class SOSAT.constraints.stress_measurement_constraint.StressMeasurement(shmin_dist)[source]
Bases:
SOSAT.constraints.constraint_base.StressConstraintA class to incorporate mini-frac or extended leakoff test (XLOT) data to constrain the state of stress
No public attributes
- shmin_distsubclass of scipy.stats.rv_continuous
The probability distribution for the measured minimum horizontal stress
This assumes that the minimum principal stress, which is measured by mini-frac or XLOT tests is horizontal. This makes this class only applicable to normal faulting or strike-slip stress environments
SOSAT.samplers.rejection_sampler
SOSAT.cli module
Console script for SOSAT. Not yet implemented