#2852 OPM flowdiag upgrade. Copy from repos

This commit is contained in:
Bjørn Erik Jensen 2018-05-07 12:55:46 +02:00
parent fb518117c0
commit ff628fa9dd
39 changed files with 2829 additions and 460 deletions

View File

@ -19,10 +19,10 @@ set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f")
set(ECL_GITHUB_SHA "0188b08081eb1ac4ade89ac224b8128b4c9b0481")
# https://github.com/OPM/opm-flowdiagnostics
set(OPM_FLOWDIAGNOSTICS_SHA "7e2be931d430796ed42efcfb5c6b67a8d5962f7f")
set(OPM_FLOWDIAGNOSTICS_SHA "f8af0914f8b1ddcda41f040f539c945a6057f5e4")
# https://github.com/OPM/opm-flowdiagnostics-applications
set(OPM_FLOWDIAGNOSTICS_APPLICATIONS_SHA "5bcd6d99259a63f5cd820db541b45c4f07aec808")
set(OPM_FLOWDIAGNOSTICS_APPLICATIONS_SHA "e769c492ccd3fc4e1f834ed60f4f9279ba8524bc")
# https://github.com/OPM/opm-parser/blob/master/opm/parser/eclipse/Units/Units.hpp
# This file was moved from opm-core to opm-parser october 2016

View File

@ -56,9 +56,9 @@ include(OpmInit)
macro (dir_hook)
endmacro (dir_hook)
# Look for the opm-data repository; if found the variable
# HAVE_OPM_DATA will be set to true.
include (Findopm-data)
# Look for the "opm-tests" repository (OPM's Regression Test data
# repository)--HAVE_OPM_TESTS true if found.
include (Findopm-tests)
# list of prerequisites for this particular project; this is in a
# separate file (in cmake/Modules sub-directory) because it is shared
@ -93,6 +93,7 @@ endmacro (install_hook)
# all setup common to the OPM library modules is done here
include (OpmLibMain)
if (HAVE_OPM_DATA)
if (HAVE_OPM_TESTS)
# Regression test data available. Enable additional tests.
include (${CMAKE_CURRENT_SOURCE_DIR}/AcceptanceTests.cmake)
endif()

View File

@ -5,9 +5,9 @@
Module: opm-flowdiagnostics-applications
Description: flow diagnostics applications and examples
Version: 2018.04-pre
Label: 2018.04-pre
Version: 2018.10-pre
Label: 2018.10-pre
Maintainer: bard.skaflestad@sintef.no
MaintainerName: Bård Skaflestad
Url: http://opm-project.org
Depends: opm-common opm-flowdiagnostics opm-core
Depends: opm-common opm-flowdiagnostics

View File

@ -23,7 +23,7 @@
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/common/utility/parameters/ParameterGroup.hpp>
#include <opm/flowdiagnostics/ConnectivityGraph.hpp>
#include <opm/flowdiagnostics/ConnectionValues.hpp>

View File

@ -22,7 +22,7 @@
#include <config.h>
#endif
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/common/utility/parameters/ParameterGroup.hpp>
#include <opm/utility/ECLResultData.hpp>
#include <iostream>

View File

@ -35,6 +35,7 @@
#include <iomanip>
#include <ios>
#include <iostream>
#include <regex>
#include <vector>
#include <boost/filesystem.hpp>
@ -100,7 +101,7 @@ namespace {
void krg(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -115,14 +116,14 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "krg", graph);
}
void krog(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -137,14 +138,14 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "krog", graph);
}
void krow(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -159,14 +160,14 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "krow", graph);
}
void krw(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -181,7 +182,7 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "krw", graph);
}
@ -191,7 +192,7 @@ namespace {
void pcgo(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -206,14 +207,14 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "pcgo", graph);
}
void pcow(const Opm::ECLSaturationFunc& sfunc,
const int activeCell,
const bool useEPS)
const Opm::ECLSaturationFunc::SatFuncScaling& scaling)
{
using RC = Opm::ECLSaturationFunc::RawCurve;
@ -228,7 +229,7 @@ namespace {
});
const auto graph =
sfunc.getSatFuncCurve(func, activeCell, useEPS);
sfunc.getSatFuncCurve(func, activeCell, scaling);
printGraph(std::cout, "pcow", graph);
}
@ -407,13 +408,41 @@ namespace {
return acell;
}
Opm::ECLSaturationFunc::SatFuncScaling
saturationFuncScaling(const Opm::ParameterGroup& prm)
{
using T = Opm::ECLSaturationFunc::SatFuncScaling::Type;
const auto opt =
std::regex_constants::icase |
std::regex_constants::ECMAScript;
const auto horiz = std::regex { "horizontal", opt };
const auto vert = std::regex { "vertical" , opt };
const auto useEPS =
prm.getDefault("useEPS", std::string{"off"});
auto scaling = Opm::ECLSaturationFunc::SatFuncScaling{};
scaling.enable = static_cast<unsigned char>(0);
scaling.invalid = handleInvalid(prm);
if (std::regex_search(useEPS, horiz)) {
scaling.enable |= T::Horizontal;
}
if (std::regex_search(useEPS, vert)) {
scaling.enable |= T::Vertical;
}
return scaling;
}
} // namespace Anonymous
int main(int argc, char* argv[])
try {
const auto prm = example::initParam(argc, argv);
const auto useEPS = prm.getDefault("useEPS", false);
const auto h_inv = handleInvalid(prm);
const auto scaling = saturationFuncScaling(prm);
const auto rset = example::identifyResultSet(prm);
const auto init = Opm::ECLInitFileData(rset.initFile());
@ -421,7 +450,7 @@ try {
const auto cellID = getActiveCell(graph, prm);
auto sfunc = Opm::ECLSaturationFunc(graph, init, useEPS, h_inv);
auto sfunc = Opm::ECLSaturationFunc(graph, init);
auto pvtCC = Opm::ECLPVT::ECLPvtCurveCollection(graph, init);
if (prm.has("unit")) {
@ -434,15 +463,15 @@ try {
// -----------------------------------------------------------------
// Relative permeability
if (prm.getDefault("krg" , false)) { krg (sfunc, cellID, useEPS); }
if (prm.getDefault("krog", false)) { krog(sfunc, cellID, useEPS); }
if (prm.getDefault("krow", false)) { krow(sfunc, cellID, useEPS); }
if (prm.getDefault("krw" , false)) { krw (sfunc, cellID, useEPS); }
if (prm.getDefault("krg" , false)) { krg (sfunc, cellID, scaling); }
if (prm.getDefault("krog", false)) { krog(sfunc, cellID, scaling); }
if (prm.getDefault("krow", false)) { krow(sfunc, cellID, scaling); }
if (prm.getDefault("krw" , false)) { krw (sfunc, cellID, scaling); }
// -----------------------------------------------------------------
// Capillary pressure
if (prm.getDefault("pcgo", false)) { pcgo(sfunc, cellID, useEPS); }
if (prm.getDefault("pcow", false)) { pcow(sfunc, cellID, useEPS); }
if (prm.getDefault("pcgo", false)) { pcgo(sfunc, cellID, scaling); }
if (prm.getDefault("pcow", false)) { pcow(sfunc, cellID, scaling); }
// -----------------------------------------------------------------
// PVT Curves

View File

@ -17,10 +17,8 @@ set (opm-flowdiagnostics-applications_DEPS
# Prerequisite OPM modules
# common -> Parameter System
# fdiag -> Solver
# parser -> Unit Conversions
"opm-common REQUIRED"
"opm-flowdiagnostics REQUIRED"
"opm-parser REQUIRED"
)
find_package_deps(opm-flowdiagnostics-applications)

View File

@ -127,6 +127,52 @@ namespace Opm { namespace SatFunc {
virtual ~EPSEvalInterface();
};
/// Protocol for computing vertically scaled relative permeability and
/// capillary pressure values.
class VerticalScalingInterface
{
public:
struct FunctionValues {
struct Point {
double sat;
double val;
};
Point disp;
Point max;
};
/// Associate a saturation value to a specific cell.
using SaturationAssoc = EPSEvalInterface::SaturationAssoc;
/// Convenience type alias.
using SaturationPoints = EPSEvalInterface::SaturationPoints;
/// Compute vertically scaled saturation function values.
///
/// \param[in] f Unscaled function values extracted from input's
/// saturation function table.
///
/// \param[in] sp Sequence of saturation points.
///
/// \param[in] val Sequence of saturation function values.
///
/// \return Sequence of vertically scaled saturation function values
/// in order of the input sequence. In particular the \c i-th
/// element of this result is the scaled version of \code val[i]
/// \endcode.
virtual std::vector<double>
vertScale(const FunctionValues& f,
const SaturationPoints& sp,
const std::vector<double>& val) const = 0;
/// Virtual copy constructor.
virtual std::unique_ptr<VerticalScalingInterface> clone() const = 0;
/// Destructor. Must be virtual.
virtual ~VerticalScalingInterface();
};
/// Implementation of ECLIPSE's standard, two-point, saturation scaling
/// option.
class TwoPointScaling : public EPSEvalInterface
@ -141,19 +187,8 @@ namespace Opm { namespace SatFunc {
/// \param[in] smin Left end points for a set of cells.
///
/// \param[in] smax Right end points for a set of cells.
///
/// \param[in] handle_invalid How to treat scaling requests with
/// invalid scaled saturations. This can, for instance, happen
/// if the scaled saturations are present in the result set but
/// some (or all) cells have irreconcilable values (e.g., minimum
/// saturation greater than maximum saturation, smin < -1E+20,
/// smax < -1E+20).
///
/// Default behaviour: Use unscaled saturation if this happens.
TwoPointScaling(std::vector<double> smin,
std::vector<double> smax,
const InvalidEndpointBehaviour handle_invalid
= InvalidEndpointBehaviour::UseUnscaled);
std::vector<double> smax);
/// Destructor.
~TwoPointScaling();
@ -244,6 +279,74 @@ namespace Opm { namespace SatFunc {
std::unique_ptr<Impl> pImpl_;
};
/// Implementation of ECLIPSE's standard, pure vertical saturation
/// function scaling option.
///
/// Multiplies function values with a location (cell ID) dependent
/// factor. Applies to both relative permeability and capillary
/// pressure functions.
class PureVerticalScaling : public VerticalScalingInterface
{
public:
/// Constructor.
///
/// Typically set up to define vertical scaling of saturation
/// function values in all active cells in a model, but could
/// alternatively be used as a means to computing the effective
/// saturation function value of a single cell.
///
/// \param[in] fmax Scaled maximum saturation function (Kr or Pc)
/// value in collection of cells. Typically an input vector like
/// PCG or KROW from an ECL result set.
explicit PureVerticalScaling(std::vector<double> fmax);
/// Destructor.
virtual ~PureVerticalScaling();
/// Copy constructor.
PureVerticalScaling(const PureVerticalScaling& rhs);
/// Move constructor.
PureVerticalScaling(PureVerticalScaling&& rhs);
/// Assignment operator.
PureVerticalScaling& operator=(const PureVerticalScaling& rhs);
/// Move assignment operator.
PureVerticalScaling& operator=(PureVerticalScaling&& rhs);
/// Compute vertically scaled saturation function values.
///
/// \param[in] f Unscaled function values extracted from input's
/// saturation function table. Method \c PureVerticalScaling
/// uses the maximum value/point only.
///
/// \param[in] sp Sequence of saturation points.
///
/// \param[in] val Sequence of saturation function values.
///
/// \return Sequence of vertically scaled saturation function values
/// in order of the input sequence. In particular the \c i-th
/// element of this result is the scaled version of \code val[i]
/// \endcode. Multiplies entries in \p val with an appropriate
/// location dependent factor.
virtual std::vector<double>
vertScale(const FunctionValues& f,
const SaturationPoints& sp,
const std::vector<double>& val) const override;
/// Virtual copy constructor.
virtual std::unique_ptr<VerticalScalingInterface>
clone() const override;
private:
/// Implementation class.
class Impl;
/// Pimpl idiom.
std::unique_ptr<Impl> pImpl_;
};
/// Implementation of ECLIPSE's alternative, three-point, saturation
/// scaling option.
class ThreePointScaling : public EPSEvalInterface
@ -261,20 +364,9 @@ namespace Opm { namespace SatFunc {
/// for a set of cells.
///
/// \param[in] smax Right end points for a set of cells.
///
/// \param[in] handle_invalid How to treat scaling requests with
/// invalid scaled saturations. This can, for instance, happen
/// if the scaled saturations are present in the result set but
/// some (or all) cells have irreconcilable values (e.g., minimum
/// saturation greater than maximum saturation, smin < -1E+20,
/// smax < -1E+20).
///
/// Default behaviour: Use unscaled saturation if this happens.
ThreePointScaling(std::vector<double> smin,
std::vector<double> sdisp,
std::vector<double> smax,
const InvalidEndpointBehaviour handle_invalid
= InvalidEndpointBehaviour::UseUnscaled);
std::vector<double> smax);
/// Destructor.
~ThreePointScaling();
@ -365,6 +457,67 @@ namespace Opm { namespace SatFunc {
std::unique_ptr<Impl> pImpl_;
};
/// Implementation of ECLIPSE's option for vertical scaling of relative
/// permeability functions honouring critical/residual saturation of
/// displacing phase.
///
/// Multiplies function values with a location (cell ID) and saturation
/// dependent factor. Not intended for capillary pressure functions.
class CritSatVerticalScaling : public VerticalScalingInterface
{
public:
/// Constructor.
explicit CritSatVerticalScaling(std::vector<double> sdisp,
std::vector<double> fdisp,
std::vector<double> fmax);
/// Destructor.
virtual ~CritSatVerticalScaling();
/// Copy constructor.
CritSatVerticalScaling(const CritSatVerticalScaling& rhs);
/// Move constructor.
CritSatVerticalScaling(CritSatVerticalScaling&& rhs);
/// Assignment operator.
CritSatVerticalScaling& operator=(const CritSatVerticalScaling& rhs);
/// Move assignment operator.
CritSatVerticalScaling& operator=(CritSatVerticalScaling&& rhs);
/// Compute vertically scaled saturation function values.
///
/// \param[in] f Unscaled function values extracted from input's
/// saturation function table. The critical saturation vertical
/// scaling method uses both the displacement and the maximum
/// points.
///
/// \param[in] sp Sequence of saturation points.
///
/// \param[in] val Sequence of saturation function values.
///
/// \return Sequence of vertically scaled saturation function values
/// in order of the input sequence. In particular the \c i-th
/// element of this result is the scaled version of \code val[i]
/// \endcode.
virtual std::vector<double>
vertScale(const FunctionValues& f,
const SaturationPoints& sp,
const std::vector<double>& val) const override;
/// Virtual copy constructor.
virtual std::unique_ptr<VerticalScalingInterface>
clone() const override;
private:
/// Implementation class.
class Impl;
/// Pimpl idiom.
std::unique_ptr<Impl> pImpl_;
};
/// Named constructors for enabling saturation end-point scaling from an
/// ECL result set (see class \c ECLInitFileData).
struct CreateEPS
@ -494,47 +647,121 @@ namespace Opm { namespace SatFunc {
Maximum smax;
};
/// Construct an EPS evaluator from a particular ECL result set.
/// Named constructors for horizontal (saturation) end-point scaling
/// of saturation functions.
struct Horizontal {
/// Construct a horizontal EPS evaluator from a particular ECL
/// result set.
///
/// \param[in] G Connected topology of current model's active cells.
/// Needed to linearise table end-points that may be distributed
/// on local grids to all of the model's active cells (\code
/// member function G.rawLinearisedCellData() \endcode).
/// \param[in] G Connected topology of current model's active
/// cells. Needed to linearise table end-points that may be
/// distributed on local grids to all of the model's active
/// cells (\code member function G.rawLinearisedCellData()
/// \endcode).
///
/// \param[in] init Container of tabulated saturation functions and
/// saturation table end points for all active cells.
/// \param[in] init Container of tabulated saturation functions
/// and saturation table end points for all active cells.
///
/// \param[in] opt Options that identify a particular end-point
/// scaling behaviour of a particular saturation function curve.
/// scaling behaviour of a particular saturation function
/// curve.
///
/// \return EPS evaluator for the particular curve defined by the
/// input options.
/// \return EPS evaluator for the particular curve defined by
/// the input options.
static std::unique_ptr<EPSEvalInterface>
fromECLOutput(const ECLGraph& G,
const ECLInitFileData& init,
const EPSOptions& opt);
/// Extract table end points relevant to a particular EPS evaluator
/// from raw tabulated saturation functions.
/// Extract table end points relevant to a particular horizontal
/// EPS evaluator from raw tabulated saturation functions.
///
/// \param[in] ep Collection of all raw table saturation end points
/// for all tabulated saturation functions. Typically computed
/// by direct calls to the \code connateSat() \endcode, \code
/// criticalSat() \endcode, and \code maximumSat() \endcode of
/// the currently active \code Opm::SatFuncInterpolant \code
/// objects.
/// \param[in] ep Collection of all raw table saturation end
/// points for all tabulated saturation functions. Typically
/// computed by direct calls to the \code connateSat()
/// \endcode, \code criticalSat() \endcode, and \code
/// maximumSat() \endcode of the currently active \code
/// Opm::SatFuncInterpolant \code objects.
///
/// \param[in] opt Options that identify a particular end-point
/// scaling behaviour of a particular saturation function curve.
/// scaling behaviour of a particular saturation function
/// curve.
///
/// \return Subset of the input end points in a format intended for
/// passing as the first argument of member function \code eval()
/// \endcode of the \code EPSEvalInterface \endcode that
/// corresponds to the input options.
/// \return Subset of the input end points in a format intended
/// for passing as the first argument of member function
/// \code eval() \endcode of the \code EPSEvalInterface
/// \endcode that corresponds to the input options.
static std::vector<EPSEvalInterface::TableEndPoints>
unscaledEndPoints(const RawTableEndPoints& ep,
const EPSOptions& opt);
};
/// Named constructors for vertical (value) scaling of saturation
/// functions.
struct Vertical {
using SatFuncEvaluator = std::function<double(int, double)>;
using FuncValVector = std::vector<
VerticalScalingInterface::FunctionValues>;
/// Construct a vertical saturation function value scaling from
/// a particular ECL result set.
///
/// \param[in] G Connected topology of current model's active
/// cells. Needed to linearise table end-points that may be
/// distributed on local grids to all of the model's active
/// cells (member functions \code G.rawLinearisedCellData()
/// \endcode and \code G.linearisedCellData() \endcode).
///
/// \param[in] init Container of tabulated saturation functions
/// and saturation table end points for all active cells.
///
/// \param[in] opt Options that identify a particular end-point
/// scaling behaviour of a particular saturation function
/// curve.
///
/// \param[in] tep Table end-points. Used to define critical
/// saturations of displacing phase for vertical scaling at
/// displacing saturation. Otherwise unused.
///
/// \param[in] fvals Function values at selected saturation
/// points. Typically constructed by means of function
/// unscaledFunctionValues().
///
/// \return Vertical scaling operator for the particular curve
/// defined by the input options.
static std::unique_ptr<VerticalScalingInterface>
fromECLOutput(const ECLGraph& G,
const ECLInitFileData& init,
const EPSOptions& opt,
const RawTableEndPoints& tep,
const FuncValVector& fvals);
/// Extract table end points relevant to a particular vertical
/// scaling evaluator from raw tabulated saturation functions.
///
/// \param[in] ep Collection of all raw table saturation end
/// points for all tabulated saturation functions. Typically
/// computed by direct calls to the \code connateSat()
/// \endcode, \code criticalSat() \endcode, and \code
/// maximumSat() \endcode of the currently active \code
/// Opm::SatFuncInterpolant \code objects.
///
/// \param[in] opt Options that identify a particular end-point
/// scaling behaviour of a particular saturation function
/// curve.
///
/// \return Subset of the input end points in a format intended
/// for passing as the first argument of member function
/// \code eval() \endcode of the \code EPSEvalInterface
/// \endcode that corresponds to the input options.
static std::vector<VerticalScalingInterface::FunctionValues>
unscaledFunctionValues(const ECLGraph& G,
const ECLInitFileData& init,
const RawTableEndPoints& ep,
const EPSOptions& opt,
const SatFuncEvaluator& evalSF);
};
};
}} // namespace Opm::SatFunc
#endif // OPM_ECLENDPOINTSCALING_HEADER_INCLUDED

View File

@ -21,7 +21,7 @@
#include <opm/utility/ECLPvtCommon.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/utility/ECLSaturationFunc.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <algorithm>
#include <exception>
@ -90,7 +90,7 @@ namespace {
const auto depthscale = usys->depth();
for (auto& zi : depth) {
zi = ::Opm::unit::convert::from(zi, depthscale);
zi = ::ImportedOpm::unit::convert::from(zi, depthscale);
}
return depth;
@ -183,9 +183,9 @@ namespace Opm
ECLFluxCalc::ECLFluxCalc(const ECLGraph& graph,
const ECLInitFileData& init,
const double grav,
const bool useEPS)
const bool /* useEPS */)
: graph_(graph)
, satfunc_(graph, init, useEPS)
, satfunc_(graph, init)
, rmap_(pvtnumVector(graph, init))
, neighbours_(graph.neighbours())
, transmissibility_(graph.transmissibility())

View File

@ -25,7 +25,7 @@
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <algorithm>
#include <array>
@ -604,7 +604,7 @@ ECL::getPVolVector(const ecl_grid_type* G,
getUnitSystem(init, gridID)->reservoirVolume();
for (auto& pv : pvol) {
pv = ::Opm::unit::convert::from(pv, pvol_unit);
pv = ::ImportedOpm::unit::convert::from(pv, pvol_unit);
}
}
@ -1157,7 +1157,7 @@ connectionData(const ::Opm::ECLRestartData& rstrt,
"Direction must be I, J, or K");
for (const auto& cell : cells->second) {
x.push_back(::Opm::unit::convert::from(v[cell], unit));
x.push_back(::ImportedOpm::unit::convert::from(v[cell], unit));
}
}
@ -1208,7 +1208,7 @@ deriveNeighbours(const std::vector<std::size_t>& gcells,
auto SI_trans = [trans_unit](const double trans)
{
return ::Opm::unit::convert::from(trans, trans_unit);
return ::ImportedOpm::unit::convert::from(trans, trans_unit);
};
auto& ocell = this->outCell_[d];
@ -1288,6 +1288,9 @@ public:
/// Retrieve number of active cells in graph.
std::size_t numCells() const;
/// Retrieve number of active cells in particular subgrid.
std::size_t numCells(const std::string& gridID) const;
/// Retrieve number of connections in graph.
std::size_t numConnections() const;
@ -1364,6 +1367,24 @@ public:
rawLinearisedCellData(const ResultSet& rset,
const std::string& vector) const;
/// Retrieve result set vector from current view (e.g., particular
/// report step) linearised on active cells of a particular sub-grid.
///
/// \tparam T Element type of result set vector.
///
/// \param[in] vector Name of result set vector.
///
/// \param[in] gridID Identity of specific grid to which to relate the
/// requested vector. Use empty for main grid and names for any
/// LGRs.
///
/// \return Result set vector linearised on active cells of sub-grid.
template <typename T, class ResultSet>
std::vector<T>
rawLinearisedCellData(const ResultSet& rset,
const std::string& vector,
const std::string& gridID) const;
/// Retrieve floating-point result set vector from current view
/// (e.g., particular report step) linearised on active cells and
/// converted to strict SI unit conventions.
@ -1776,7 +1797,7 @@ NNC::add(const std::vector<ECL::CartesianGridData>& grid,
// Capture transmissibility field to support on-demand flux calculations
// if flux fields are not output to the on-disk result set.
this->trans_.push_back(unit::convert::from(nnc.trans, trans_unit));
this->trans_.push_back(ImportedOpm::unit::convert::from(nnc.trans, trans_unit));
const auto cat = this->classifyConnection(nnc.grid_nr1, nnc.grid_nr2);
@ -1997,6 +2018,15 @@ Opm::ECLGraph::Impl::numCells() const
return this->activeOffset_.back();
}
std::size_t
Opm::ECLGraph::Impl::numCells(const std::string& gridID) const
{
auto i = this->gridID_.find(gridID);
return (i == std::end(this->gridID_))
? 0 : this->grid_[i->second].numCells();
}
std::size_t
Opm::ECLGraph::Impl::numConnections() const
{
@ -2185,6 +2215,21 @@ namespace Opm {
return x;
}
template <typename T, class ResultSet>
std::vector<T>
ECLGraph::Impl::rawLinearisedCellData(const ResultSet& rset,
const std::string& vector,
const std::string& gridID) const
{
auto i = this->gridID_.find(gridID);
if (i == std::end(this->gridID_)) {
return {};
}
return this->grid_[i->second].activeCellData<T>(rset, vector);
}
} // namespace Opm
std::vector<double>
@ -2211,7 +2256,7 @@ Opm::ECLGraph::Impl::linearisedCellData(const ECLRestartData& rstrt,
std::back_inserter(x),
[vector_unit](const double value)
{
return ::Opm::unit::convert::from(value, vector_unit);
return ::ImportedOpm::unit::convert::from(value, vector_unit);
});
}
@ -2285,7 +2330,7 @@ Opm::ECLGraph::Impl::fluxNNC(const ECLRestartData& rstrt,
assert (ix.kwIdx < q.size());
v[ix.neighIdx] =
unit::convert::from(q[ix.kwIdx], flux_unit);
ImportedOpm::unit::convert::from(q[ix.kwIdx], flux_unit);
assigned[ix.neighIdx] = true;
}
@ -2408,6 +2453,11 @@ std::size_t Opm::ECLGraph::numCells() const
return this->pImpl_->numCells();
}
std::size_t Opm::ECLGraph::numCells(const std::string& gridID) const
{
return this->pImpl_->numCells(gridID);
}
std::size_t Opm::ECLGraph::numConnections() const
{
return this->pImpl_->numConnections();
@ -2462,6 +2512,15 @@ namespace Opm {
return this->pImpl_->rawLinearisedCellData<T>(rset, vector);
}
template <typename T, class ResultSet>
std::vector<T>
ECLGraph::rawLinearisedCellData(const ResultSet& rset,
const std::string& vector,
const std::string& gridID) const
{
return this->pImpl_->rawLinearisedCellData<T>(rset, vector, gridID);
}
// Explicit instantiations of method rawLinearisedCellData() for the
// element and result set types we care about.
template std::vector<int>
@ -2480,6 +2539,26 @@ namespace Opm {
ECLGraph::rawLinearisedCellData<double>(const ECLRestartData& rset,
const std::string& vector) const;
template std::vector<int>
ECLGraph::rawLinearisedCellData<int>(const ECLInitFileData& rset,
const std::string& vector,
const std::string& gridID) const;
template std::vector<int>
ECLGraph::rawLinearisedCellData<int>(const ECLRestartData& rset,
const std::string& vector,
const std::string& gridID) const;
template std::vector<double>
ECLGraph::rawLinearisedCellData<double>(const ECLInitFileData& rset,
const std::string& vector,
const std::string& gridID) const;
template std::vector<double>
ECLGraph::rawLinearisedCellData<double>(const ECLRestartData& rset,
const std::string& vector,
const std::string& gridID) const;
} // namespace Opm
std::vector<double>

View File

@ -111,11 +111,14 @@ namespace Opm {
/// outside valid range or if the specific cell identified by \p
/// ijk and \p gridID is not actually active.
int activeCell(const std::array<int,3>& ijk,
const std::string& gridID = 0) const;
const std::string& gridID = "") const;
/// Retrieve number of active cells in graph.
std::size_t numCells() const;
/// Retrieve number of active cells in particular subgrid.
std::size_t numCells(const std::string& gridID) const;
/// Retrieve number of connections in graph.
std::size_t numConnections() const;
@ -183,6 +186,24 @@ namespace Opm {
rawLinearisedCellData(const ResultSet& rset,
const std::string& vector) const;
/// Retrieve result set vector from current view (e.g., particular
/// report step) linearised on active cells of a particular sub-grid.
///
/// \tparam T Element type of result set vector.
///
/// \param[in] vector Name of result set vector.
///
/// \param[in] gridID Identity of specific grid to which to relate
/// the requested vector. Use empty for main grid and names for
/// any LGRs.
///
/// \return Result set vector linearised on active cells of sub-grid.
template <typename T, class ResultSet>
std::vector<T>
rawLinearisedCellData(const ResultSet& rset,
const std::string& vector,
const std::string& gridID) const;
/// Convenience type alias for \c UnitSystem PMFs (pointer to member
/// function).
typedef double (ECLUnits::UnitSystem::*UnitConvention)() const;

View File

@ -22,7 +22,7 @@
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <ert/ecl/ecl_kw_magic.h>
@ -315,7 +315,7 @@ namespace {
double calculateScaleFactor(const double from, const double to)
{
using namespace ::Opm::unit;
using namespace ::ImportedOpm::unit;
// "return from / to", essentially.
return convert::to(convert::from(1.0, from), to);

View File

@ -22,7 +22,7 @@
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <functional>
#include <utility>
@ -64,7 +64,7 @@ namespace {
return ::Opm::ECLPVT::ConvertUnits::Converter {
[uscale](const double q) -> double
{
return ::Opm::unit::convert::from(q, uscale);
return ::ImportedOpm::unit::convert::from(q, uscale);
}
};
}
@ -326,7 +326,7 @@ Opm::ECLPVT::surfaceMassDensity(const ECLInitFileData& init,
const auto dens_scale = u->density();
for (auto& rho_i : rho) {
rho_i = unit::convert::from(rho_i, dens_scale);
rho_i = ImportedOpm::unit::convert::from(rho_i, dens_scale);
}
return rho;

View File

@ -25,7 +25,7 @@
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <cassert>
#include <cmath>

View File

@ -24,7 +24,7 @@
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <cassert>
#include <cmath>
@ -48,7 +48,7 @@ namespace {
return [scale](const double x) -> double
{
return Opm::unit::convert::from(x, scale);
return ImportedOpm::unit::convert::from(x, scale);
};
}
@ -59,7 +59,7 @@ namespace {
return [scale](const double x) -> double
{
return Opm::unit::convert::from(x, scale);
return ImportedOpm::unit::convert::from(x, scale);
};
}

View File

@ -79,8 +79,26 @@ namespace Opm {
ECLPhaseIndex thisPh;
};
using InvalidEPBehaviour = ::Opm::SatFunc::
EPSEvalInterface::InvalidEndpointBehaviour;
struct SatFuncScaling {
enum Type : unsigned char {
Horizontal = 1 << 0u,
Vertical = 1 << 1u,
};
using IEB = SatFunc::EPSEvalInterface::InvalidEndpointBehaviour;
SatFuncScaling()
: enable (Type::Horizontal | Type::Vertical)
, invalid(IEB::UseUnscaled)
{}
// Default: Use both Horizontal and Vertical if specified.
unsigned char enable;
// Default: Use unscaled values in case of invalid scaled
// saturations occurring in the result set.
IEB invalid;
};
/// Constructor
///
@ -92,27 +110,8 @@ namespace Opm {
/// \param[in] init Container of tabulated saturation functions and
/// saturation table end points, if applicable, for all active
/// cells in the model \p G.
///
/// \param[in] useEPS Whether or not to include effects of
/// saturation end-point scaling. No effect if the INIT result
/// set does not actually include saturation end-point scaling
/// data. Otherwise, enables turning EPS off even if associate
/// data is present in the INIT result set.
///
/// Default value (\c true) means that effects of EPS are
/// included if requisite data is present in the INIT result.
///
/// \param[in] handle_invalid Run-time policy for how to handle
/// scaling requests relative to invalid scaled saturations
/// (e.g., SWL = -1.0E+20).
///
/// Default value (\c UseUnscaled) means that invalid scalings
/// are treated as unscaled.
ECLSaturationFunc(const ECLGraph& G,
const ECLInitFileData& init,
const bool useEPS = true,
const InvalidEPBehaviour handle_invalid
= InvalidEPBehaviour::UseUnscaled);
const ECLInitFileData& init);
/// Destructor.
~ECLSaturationFunc();
@ -253,6 +252,69 @@ namespace Opm {
const int activeCell,
const bool useEPS = true) const;
/// Retrieve 2D graph representations of sequence of effective
/// saturation functions in a single cell.
///
/// \param[in] func Sequence of saturation function descriptions.
///
/// \param[in] activeCell Index of active cell from which to derive
/// the effective saturation function. Use member function \code
/// ECLGraph::activeCell() \endcode to translate a global cell
/// (I,J,K) tuple--relative to a model grid--to a linear active
/// cell ID.
///
/// \param[in] scaling Which type of saturation function scaling to
/// apply. No effect if the INIT result set from which the
/// object was constructed does not actually include saturation
/// end-point scaling or function value scaling data. Otherwise,
/// enables turning various scaling effects on or off even if
/// associate data is present in the INIT result set.
///
/// \return Sequence of 2D graphs for all saturation function
/// requests represented by \p func. In particular, the \c i-th
/// element of the result corresponds to input request \code
/// func[i] \endcode. Abscissas are stored in \code
/// graph[i].first \endcode and ordinates are stored in \code
/// graph[i].second \endcode. If a particular request is
/// semantically invalid, such as when requesting the water
/// relative permeability in the oil-gas system, then the
/// corresponding graph in the result is empty.
///
/// Example: Retrieve relative permeability curves for oil in active
/// cell 2718 in both the oil-gas and oil-water sub-systems
/// including effects of vertical scaling only.
///
/// \code
/// using RC = ECLSaturationFunc::RawCurve;
/// auto func = std::vector<RC>{};
/// func.reserve(2);
///
/// // Request krog (oil rel-perm in oil-gas system)
/// func.push_back(RC{
/// RC::Function::RelPerm,
/// RC::SubSystem::OilGas,
/// ECLPhaseIndex::Liquid
/// });
///
/// // Request krow (oil rel-perm in oil-water system)
/// func.push_back(RC{
/// RC::Function::RelPerm,
/// RC::SubSystem::OilWater,
/// ECLPhaseIndex::Liquid
/// });
///
/// auto scaling = SatFuncScaling{};
/// scaling.enable = static_cast<unsigned char>(0);
/// scaling.enable |= SatFuncScaling::Type::Vertical;
///
/// const auto graph =
/// sfunc.getSatFuncCurve(func, 2718, scaling);
/// \endcode
std::vector<FlowDiagnostics::Graph>
getSatFuncCurve(const std::vector<RawCurve>& func,
const int activeCell,
const SatFuncScaling& scaling) const;
private:
/// Implementation backend.
class Impl;

View File

@ -23,7 +23,7 @@
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <exception>
#include <stdexcept>
@ -38,6 +38,8 @@ namespace Opm { namespace ECLUnits {
template <ert_ecl_unit_enum convention>
class USys;
using namespace ImportedOpm;
template <>
class USys<ECL_METRIC_UNITS> : public ::Opm::ECLUnits::UnitSystem
{

View File

@ -25,7 +25,7 @@
#include <opm/utility/ECLWellSolution.hpp>
#include <opm/utility/ECLResultData.hpp>
#include <opm/utility/ECLUnitHandling.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/utility/imported/Units.hpp>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl_well/well_const.h>
#include <cmath>
@ -217,6 +217,7 @@ namespace Opm
for (int well = 0; well < ih.nwell; ++well) {
// Skip if total rate below threshold (for wells that are
// shut or stopped for example).
using namespace ImportedOpm;
const double well_reservoir_inflow_rate = -unit::convert::from(xwel[well * ih.nxwel + XWEL_RESV_INDEX], qr_unit);
if (std::fabs(well_reservoir_inflow_rate) < rate_threshold_) {
continue;

View File

@ -0,0 +1,367 @@
//===========================================================================
//
// File: Units.hpp
//
// Created: Thu Jul 2 09:19:08 2009
//
// Author(s): Halvor M Nilsen <hnil@sintef.no>
//
// $Date$
//
// $Revision$
//
//===========================================================================
/*
Copyright 2009, 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010, 2011, 2012 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IMPORTED_OPM_UNITS_HEADER
#define IMPORTED_OPM_UNITS_HEADER
// WARNING!
// This file is a modified duplicate, imported to make this module independent.
// Modifications include file location, the header guard, and using the ImportedOpm namespace.
/**
The unit sets emplyed in ECLIPSE, in particular the FIELD units,
are quite inconsistent. Ideally one should choose units for a set
of base quantities like Mass,Time and Length and then derive the
units for e.g. pressure and flowrate in a consisten manner. However
that is not the case; for instance in the metric system we have:
[Length] = meters
[time] = days
[mass] = kg
This should give:
[Pressure] = [mass] / ([length] * [time]^2) = kg / (m * days * days)
Instead pressure is given in Bars. When it comes to FIELD units the
number of such examples is long.
*/
namespace ImportedOpm {
namespace prefix
/// Conversion prefix for units.
{
constexpr const double micro = 1.0e-6; /**< Unit prefix [\f$\mu\f$] */
constexpr const double milli = 1.0e-3; /**< Unit prefix [m] */
constexpr const double centi = 1.0e-2; /**< Non-standard unit prefix [c] */
constexpr const double deci = 1.0e-1; /**< Non-standard unit prefix [d] */
constexpr const double kilo = 1.0e3; /**< Unit prefix [k] */
constexpr const double mega = 1.0e6; /**< Unit prefix [M] */
constexpr const double giga = 1.0e9; /**< Unit prefix [G] */
} // namespace prefix
namespace unit
/// Definition of various units.
/// All the units are defined in terms of international standard
/// units (SI). Example of use: We define a variable \c k which
/// gives a permeability. We want to set \c k to \f$1\,mD\f$.
/// \code
/// using namespace Opm::unit
/// double k = 0.001*darcy;
/// \endcode
/// We can also use one of the prefixes defined in Opm::prefix
/// \code
/// using namespace Opm::unit
/// using namespace Opm::prefix
/// double k = 1.0*milli*darcy;
/// \endcode
{
///\name Common powers
/// @{
constexpr double square(double v) { return v * v; }
constexpr double cubic (double v) { return v * v * v; }
/// @}
// --------------------------------------------------------------
// Basic (fundamental) units and conversions
// --------------------------------------------------------------
/// \name Length
/// @{
constexpr const double meter = 1;
constexpr const double inch = 2.54 * prefix::centi*meter;
constexpr const double feet = 12 * inch;
/// @}
/// \name Time
/// @{
constexpr const double second = 1;
constexpr const double minute = 60 * second;
constexpr const double hour = 60 * minute;
constexpr const double day = 24 * hour;
constexpr const double year = 365 * day;
/// @}
/// \name Volume
/// @{
constexpr const double gallon = 231 * cubic(inch);
constexpr const double stb = 42 * gallon;
constexpr const double liter = 1 * cubic(prefix::deci*meter);
/// @}
/// \name Mass
/// @{
constexpr const double kilogram = 1;
constexpr const double gram = 1.0e-3 * kilogram;
// http://en.wikipedia.org/wiki/Pound_(mass)#Avoirdupois_pound
constexpr const double pound = 0.45359237 * kilogram;
/// @}
/// \name Energy
/// @{
constexpr const double joule = 1;
constexpr const double btu = 1054.3503*joule; // "british thermal units"
/// @}
// --------------------------------------------------------------
// Standardised constants
// --------------------------------------------------------------
/// \name Standardised constant
/// @{
constexpr const double gravity = 9.80665 * meter/square(second);
/// @}
// --------------------------------------------------------------
// Derived units and conversions
// --------------------------------------------------------------
/// \name Force
/// @{
constexpr const double Newton = kilogram*meter / square(second); // == 1
constexpr const double dyne = 1e-5*Newton;
constexpr const double lbf = pound * gravity; // Pound-force
/// @}
/// \name Pressure
/// @{
constexpr const double Pascal = Newton / square(meter); // == 1
constexpr const double barsa = 100000 * Pascal;
constexpr const double atm = 101325 * Pascal;
constexpr const double psia = lbf / square(inch);
/// @}
/// \name Temperature. This one is more complicated
/// because the unit systems used by Eclipse (i.e. degrees
/// Celsius and degrees Fahrenheit require to add or
/// subtract an offset for the conversion between from/to
/// Kelvin
/// @{
constexpr const double degCelsius = 1.0; // scaling factor °C -> K
constexpr const double degCelsiusOffset = 273.15; // offset for the °C -> K conversion
constexpr const double degFahrenheit = 5.0/9; // scaling factor °F -> K
constexpr const double degFahrenheitOffset = 255.37; // offset for the °C -> K conversion
/// @}
/// \name Viscosity
/// @{
constexpr const double Pas = Pascal * second; // == 1
constexpr const double Poise = prefix::deci*Pas;
/// @}
namespace perm_details {
constexpr const double p_grad = atm / (prefix::centi*meter);
constexpr const double area = square(prefix::centi*meter);
constexpr const double flux = cubic (prefix::centi*meter) / second;
constexpr const double velocity = flux / area;
constexpr const double visc = prefix::centi*Poise;
constexpr const double darcy = (velocity * visc) / p_grad;
// == 1e-7 [m^2] / 101325
// == 9.869232667160130e-13 [m^2]
}
/// \name Permeability
/// @{
///
/// A porous medium with a permeability of 1 darcy permits a flow (flux)
/// of \f$1\,\mathit{cm}^3/s\f$ of a fluid with viscosity
/// \f$1\,\mathit{cP}\f$ (\f$1\,mPa\cdot s\f$) under a pressure gradient
/// of \f$1\,\mathit{atm}/\mathit{cm}\f$ acting across an area of
/// \f$1\,\mathit{cm}^2\f$.
///
constexpr const double darcy = perm_details::darcy;
/// @}
/**
* Unit conversion routines.
*/
namespace convert {
/**
* Convert from external units of measurements to equivalent
* internal units of measurements. Note: The internal units of
* measurements are *ALWAYS*, and exclusively, SI.
*
* Example: Convert a double @c kx, containing a permeability value
* in units of milli-darcy (mD) to the equivalent value in SI units
* (i.e., \f$m^2\f$).
* \code
* using namespace Opm::unit;
* using namespace Opm::prefix;
* convert::from(kx, milli*darcy);
* \endcode
*
* @param[in] q Physical quantity.
* @param[in] unit Physical unit of measurement.
* @return Value of @c q in equivalent SI units of measurements.
*/
constexpr double from(const double q, const double unit)
{
return q * unit;
}
/**
* Convert from internal units of measurements to equivalent
* external units of measurements. Note: The internal units of
* measurements are *ALWAYS*, and exclusively, SI.
*
* Example: Convert a <CODE>std::vector<double> p</CODE>, containing
* pressure values in the SI unit Pascal (i.e., unit::Pascal) to the
* equivalent values in Psi (unit::psia).
* \code
* using namespace Opm::unit;
* std::transform(p.begin(), p.end(), p.begin(),
* boost::bind(convert::to, _1, psia));
* \endcode
*
* @param[in] q Physical quantity, measured in SI units.
* @param[in] unit Physical unit of measurement.
* @return Value of @c q in unit <CODE>unit</CODE>.
*/
constexpr double to(const double q, const double unit)
{
return q / unit;
}
} // namespace convert
}
namespace Metric {
using namespace prefix;
using namespace unit;
constexpr const double Pressure = barsa;
constexpr const double Temperature = degCelsius;
constexpr const double TemperatureOffset = degCelsiusOffset;
constexpr const double AbsoluteTemperature = degCelsius; // actually [K], but the these two are identical
constexpr const double Length = meter;
constexpr const double Time = day;
constexpr const double Mass = kilogram;
constexpr const double Permeability = milli*darcy;
constexpr const double Transmissibility = centi*Poise*cubic(meter)/(day*barsa);
constexpr const double LiquidSurfaceVolume = cubic(meter);
constexpr const double GasSurfaceVolume = cubic(meter);
constexpr const double ReservoirVolume = cubic(meter);
constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume;
constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume;
constexpr const double Density = kilogram/cubic(meter);
constexpr const double PolymerDensity = kilogram/cubic(meter);
constexpr const double Salinity = kilogram/cubic(meter);
constexpr const double Viscosity = centi*Poise;
constexpr const double Timestep = day;
constexpr const double SurfaceTension = dyne/(centi*meter);
constexpr const double Energy = kilo*joule;
}
namespace Field {
using namespace prefix;
using namespace unit;
constexpr const double Pressure = psia;
constexpr const double Temperature = degFahrenheit;
constexpr const double TemperatureOffset = degFahrenheitOffset;
constexpr const double AbsoluteTemperature = degFahrenheit; // actually [°R], but the these two are identical
constexpr const double Length = feet;
constexpr const double Time = day;
constexpr const double Mass = pound;
constexpr const double Permeability = milli*darcy;
constexpr const double Transmissibility = centi*Poise*stb/(day*psia);
constexpr const double LiquidSurfaceVolume = stb;
constexpr const double GasSurfaceVolume = 1000*cubic(feet);
constexpr const double ReservoirVolume = stb;
constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume;
constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume;
constexpr const double Density = pound/cubic(feet);
constexpr const double PolymerDensity = pound/stb;
constexpr const double Salinity = pound/stb;
constexpr const double Viscosity = centi*Poise;
constexpr const double Timestep = day;
constexpr const double SurfaceTension = dyne/(centi*meter);
constexpr const double Energy = btu;
}
namespace Lab {
using namespace prefix;
using namespace unit;
constexpr const double Pressure = atm;
constexpr const double Temperature = degCelsius;
constexpr const double TemperatureOffset = degCelsiusOffset;
constexpr const double AbsoluteTemperature = degCelsius; // actually [K], but the these two are identical
constexpr const double Length = centi*meter;
constexpr const double Time = hour;
constexpr const double Mass = gram;
constexpr const double Permeability = milli*darcy;
constexpr const double Transmissibility = centi*Poise*cubic(centi*meter)/(hour*atm);
constexpr const double LiquidSurfaceVolume = cubic(centi*meter);
constexpr const double GasSurfaceVolume = cubic(centi*meter);
constexpr const double ReservoirVolume = cubic(centi*meter);
constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume;
constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume;
constexpr const double Density = gram/cubic(centi*meter);
constexpr const double PolymerDensity = gram/cubic(centi*meter);
constexpr const double Salinity = gram/cubic(centi*meter);
constexpr const double Viscosity = centi*Poise;
constexpr const double Timestep = hour;
constexpr const double SurfaceTension = dyne/(centi*meter);
constexpr const double Energy = joule;
}
namespace PVT_M {
using namespace prefix;
using namespace unit;
constexpr const double Pressure = atm;
constexpr const double Temperature = degCelsius;
constexpr const double TemperatureOffset = degCelsiusOffset;
constexpr const double AbsoluteTemperature = degCelsius; // actually [K], but the these two are identical
constexpr const double Length = meter;
constexpr const double Time = day;
constexpr const double Mass = kilogram;
constexpr const double Permeability = milli*darcy;
constexpr const double Transmissibility = centi*Poise*cubic(meter)/(day*atm);
constexpr const double LiquidSurfaceVolume = cubic(meter);
constexpr const double GasSurfaceVolume = cubic(meter);
constexpr const double ReservoirVolume = cubic(meter);
constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume;
constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume;
constexpr const double Density = kilogram/cubic(meter);
constexpr const double PolymerDensity = kilogram/cubic(meter);
constexpr const double Salinity = kilogram/cubic(meter);
constexpr const double Viscosity = centi*Poise;
constexpr const double Timestep = day;
constexpr const double SurfaceTension = dyne/(centi*meter);
constexpr const double Energy = kilo*joule;
}
}
#endif // IMPORTED_OPM_UNITS_HEADER

View File

@ -44,7 +44,7 @@
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/regex.hpp>
#include <regex>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_file_kw.h>
@ -58,11 +58,11 @@ namespace StringUtils {
std::string trim(const std::string& s)
{
const auto anchor_ws =
boost::regex(R"~~(^\s+([^\s]+)\s+$)~~");
std::regex(R"~~(^\s+([^\s]+)\s+$)~~");
auto m = boost::smatch{};
auto m = std::smatch{};
if (boost::regex_match(s, m, anchor_ws)) {
if (std::regex_match(s, m, anchor_ws)) {
return m[1];
}
@ -77,9 +77,9 @@ namespace StringUtils {
return { "" };
}
const auto sep = boost::regex(R"~~([\s,;.|]+)~~");
const auto sep = std::regex(R"~~([\s,;.|]+)~~");
using TI = boost::sregex_token_iterator;
using TI = std::sregex_token_iterator;
// vector<string>(begin, end)
//

View File

@ -21,10 +21,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_ECLENDPOINTSCALING
@ -36,6 +32,7 @@
#include <opm/utility/ECLEndPointScaling.hpp>
#include <exception>
#include <initializer_list>
#include <stdexcept>
#include <vector>
@ -72,6 +69,116 @@ namespace {
return sp;
}
std::vector<double> sw_core1d_example()
{
return {
1.700000000000000e-01,
1.861700000000000e-01,
2.023400000000000e-01,
2.185110000000000e-01,
2.346810000000000e-01,
2.508510000000000e-01,
2.670210000000000e-01,
2.831910000000000e-01,
2.993620000000000e-01,
3.155320000000000e-01,
3.317020000000000e-01,
3.478720000000000e-01,
3.640430000000000e-01,
3.802130000000000e-01,
3.963830000000000e-01,
4.125530000000000e-01,
4.287230000000000e-01,
4.448940000000000e-01,
4.610640000000000e-01,
4.772340000000000e-01,
4.934040000000000e-01,
5.095740000000000e-01,
5.257450000000000e-01,
5.419150000000000e-01,
5.580850000000001e-01,
5.742550000000000e-01,
5.904260000000000e-01,
6.065960000000000e-01,
6.227660000000000e-01,
6.389359999999999e-01,
6.551060000000000e-01,
6.712770000000000e-01,
6.874470000000000e-01,
7.036170000000000e-01,
7.197870000000000e-01,
7.359570000000000e-01,
7.521280000000000e-01,
7.682980000000000e-01,
7.844680000000001e-01,
8.006380000000000e-01,
8.168090000000000e-01,
8.329790000000000e-01,
8.491490000000000e-01,
8.653189999999999e-01,
8.814890000000000e-01,
8.976600000000000e-01,
9.138300000000000e-01,
9.300000000000000e-01,
1.000000000000000e+00,
};
}
std::vector<double> krw_core1d_example()
{
return {
0,
4.526940000000000e-04,
1.810770000000000e-03,
4.074240000000000e-03,
7.243100000000000e-03,
1.131730000000000e-02,
1.629700000000000e-02,
2.218200000000000e-02,
2.897240000000000e-02,
3.666820000000000e-02,
4.526940000000000e-02,
5.477590000000000e-02,
6.518789999999999e-02,
7.650520000000000e-02,
8.872790000000000e-02,
1.018560000000000e-01,
1.158900000000000e-01,
1.308280000000000e-01,
1.466730000000000e-01,
1.634220000000000e-01,
1.810770000000000e-01,
1.996380000000000e-01,
2.191040000000000e-01,
2.394750000000000e-01,
2.607510000000000e-01,
2.829330000000000e-01,
3.060210000000000e-01,
3.300140000000000e-01,
3.549120000000000e-01,
3.807150000000000e-01,
4.074240000000000e-01,
4.350380000000000e-01,
4.635580000000000e-01,
4.929830000000000e-01,
5.233139999999999e-01,
5.545500000000000e-01,
5.866910000000000e-01,
6.197370000000000e-01,
6.536890000000000e-01,
6.885470000000000e-01,
7.243100000000000e-01,
7.609780000000000e-01,
7.985510000000000e-01,
8.370300000000001e-01,
8.764150000000001e-01,
9.167040000000000e-01,
9.579000000000000e-01,
1.000000000000000e+00,
1.000000000000000e+00,
};
}
} // Namespace Anonymous
// =====================================================================
@ -631,3 +738,330 @@ BOOST_AUTO_TEST_CASE (ScaledConnate)
}
BOOST_AUTO_TEST_SUITE_END ()
// =====================================================================
// Pure vertical scaling of SF values.
// ---------------------------------------------------------------------
BOOST_AUTO_TEST_SUITE (PureVerticalScaling_SFValues)
BOOST_AUTO_TEST_CASE (Parabola_ScaledCell)
{
using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point;
using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues;
// val = linspace(0, 1, 11) .^ 2
const auto val = std::vector<double> {
0,
1.0e-02,
4.0e-02,
9.0e-02,
1.6e-01,
2.5e-01,
3.6e-01,
4.9e-01,
6.4e-01,
8.1e-01,
1.0e+00,
};
// Maximum value in cell is 0.5.
const auto scaler = Opm::SatFunc::PureVerticalScaling({ 0.5 });
// This is a lie. We do however not actually use the sp[i].sat values
// in *this particular application (pure v-scaling)* though--we only
// care about sp[i].cell--so we can get away with pretending that the
// function values (val) are saturations.
const auto sp = associate(val);
const auto f = SFVal{
SFPt{ 0.0, 0.0 }, // Displacement
SFPt{ 1.0, 1.0 }, // Maximum
};
const auto y = scaler.vertScale(f, sp, val);
// expect = 0.5 * val
const auto expect = std::vector<double> {
0,
5.00e-03,
2.00e-02,
4.50e-02,
8.00e-02,
1.25e-01,
1.80e-01,
2.45e-01,
3.20e-01,
4.05e-01,
5.00e-01,
};
check_is_close(y, expect);
}
BOOST_AUTO_TEST_CASE (Parabola_ScaledFunc)
{
using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point;
using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues;
// val = linspace(0, 1, 11) .^ 2
const auto val = std::vector<double> {
0,
1.0e-02,
4.0e-02,
9.0e-02,
1.6e-01,
2.5e-01,
3.6e-01,
4.9e-01,
6.4e-01,
8.1e-01,
1.0e+00,
};
// Maximum value in cell is 1.
const auto scaler = Opm::SatFunc::PureVerticalScaling({ 1.0 });
// This is a lie. We do however not actually use the sp[i].sat values
// in *this particular application (pure v-scaling)* though--we only
// care about sp[i].cell--so we can get away with pretending that the
// function values (val) are saturations.
const auto sp = associate(val);
const auto f = SFVal{
SFPt{ 0.0, 0.0 }, // Displacement
SFPt{ 1.0, 2.0 }, // Maximum
};
const auto y = scaler.vertScale(f, sp, val);
// expect = val / 2
const auto expect = std::vector<double> {
0,
5.00e-03,
2.00e-02,
4.50e-02,
8.00e-02,
1.25e-01,
1.80e-01,
2.45e-01,
3.20e-01,
4.05e-01,
5.00e-01,
};
check_is_close(y, expect);
}
BOOST_AUTO_TEST_CASE (Parabola_ScaledBoth)
{
using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point;
using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues;
// val = linspace(0, 1, 11) .^ 2
const auto val = std::vector<double> {
0,
1.0e-02,
4.0e-02,
9.0e-02,
1.6e-01,
2.5e-01,
3.6e-01,
4.9e-01,
6.4e-01,
8.1e-01,
1.0e+00,
};
// Maximum value in cell is 1.5.
const auto scaler = Opm::SatFunc::PureVerticalScaling({ 1.5 });
// This is a lie. We do however not actually use the sp[i].sat values
// in *this particular application (pure v-scaling)* though--we only
// care about sp[i].cell--so we can get away with pretending that the
// function values (val) are saturations.
const auto sp = associate(val);
const auto f = SFVal{
SFPt{ 0.0, 0.0 }, // Displacement
SFPt{ 1.0, 2.0 }, // Maximum
};
const auto y = scaler.vertScale(f, sp, val);
// expect = val * 0.75
const auto expect = std::vector<double> {
0,
7.500e-03,
3.000e-02,
6.750e-02,
1.200e-01,
1.875e-01,
2.700e-01,
3.675e-01,
4.800e-01,
6.075e-01,
7.500e-01,
};
check_is_close(y, expect);
}
BOOST_AUTO_TEST_SUITE_END ()
// =====================================================================
// Critical saturation vertical scaling of SF values.
// ---------------------------------------------------------------------
BOOST_AUTO_TEST_SUITE (CritSatVScale_SFValues)
/*
sw = 0.1 : 0.05 : 0.9;
kr = sw .^ 2;
[sdisp, fdisp, fmax] = deal(0.7, 0.6, 0.7);
i = ~ (sw > sdisp);
y = 0 * kr;
y( i) = kr(i) .* fdisp./sdisp^2;
y(~i) = fdisp + (kr(~i) - sdisp^2)./(kr(end) - sdisp^2) .* (fmax - fdisp);
figure, plot(sw, [kr; y], '.-')
legend('Unscaled', 'Vert. Scaled', 'Location', 'Best')
*/
BOOST_AUTO_TEST_CASE (Sw2_Regular)
{
using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point;
using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues;
const auto sw = associate({
1.0e-01, 1.5e-01, 2.0e-01, 2.5e-01,
3.0e-01, 3.5e-01, 4.0e-01, 4.5e-01,
5.0e-01, 5.5e-01, 6.0e-01, 6.5e-01,
7.0e-01, 7.5e-01, 8.0e-01, 8.5e-01,
9.0e-01,
});
const auto kr = std::vector<double> { // sw^2
1.000e-02, 2.250e-02, 4.000e-02, 6.250e-02, // 0 .. 3
9.000e-02, 1.225e-01, 1.600e-01, 2.025e-01, // 4 .. 7
2.500e-01, 3.025e-01, 3.600e-01, 4.225e-01, // 8 .. 11
4.900e-01, 5.625e-01, 6.400e-01, 7.225e-01, // 12 .. 15
8.100e-01, // 16
};
const auto f = SFVal{
SFPt{ 0.7, 0.49 }, // Displacement
SFPt{ 0.9, 0.81 }, // Maximum
};
// Scaled residual displacement sat: 0.7
// Scaled Kr at Scaled Sr (KRxR): 0.6
// Scaled Kr at Smax: (KRx) 0.7
const auto scaler = Opm::SatFunc::
CritSatVerticalScaling({ 0.71 }, { 0.6 }, { 0.7 });
const auto y = scaler.vertScale(f, sw, kr);
// expect = kr .* (KRxR/0.49), S \le Sr
// KRxR + (kr - 0.49)/(0.81 - 0.49)*(KRx - KRxR), Sr < S
const auto expect = std::vector<double> {
1.224489795918368e-02, // 0
2.755102040816328e-02, // 1
4.897959183673471e-02, // 2
7.653061224489796e-02, // 3
1.102040816326531e-01, // 4
1.500000000000000e-01, // 5
1.959183673469388e-01, // 6
2.479591836734695e-01, // 7
3.061224489795918e-01, // 8
3.704081632653062e-01, // 9
4.408163265306123e-01, // 10
5.173469387755103e-01, // 11
// ------- Sr -------
6.000000000000000e-01, // 12
6.226562500000000e-01, // 13
6.468750000000000e-01, // 14
6.726562500000000e-01, // 15
7.000000000000000e-01, // 16
};
check_is_close(y, expect);
}
BOOST_AUTO_TEST_CASE (Core1D_Coincident_FVal)
{
using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point;
using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues;
const auto s = associate(sw_core1d_example());
const auto kr = krw_core1d_example();
const auto f = SFVal{
SFPt{ 0.93, 1.0 }, // Displacement
SFPt{ 1.0 , 1.0 }, // Maximum
};
const auto scaler = Opm::SatFunc::
CritSatVerticalScaling({ 0.93 }, { 0.9 }, { 1.0 });
const auto y = scaler.vertScale(f, s, kr);
const auto expect = std::vector<double> {
0,
4.074246000000000e-04,
1.629693000000000e-03,
3.666816000000000e-03,
6.518790000000000e-03,
1.018557000000000e-02,
1.466730000000000e-02,
1.996380000000000e-02,
2.607516000000000e-02,
3.300138000000000e-02,
4.074246000000000e-02,
4.929831000000000e-02,
5.866911000000000e-02,
6.885468000000000e-02,
7.985511000000001e-02,
9.167040000000000e-02,
1.043010000000000e-01,
1.177452000000000e-01,
1.320057000000000e-01,
1.470798000000000e-01,
1.629693000000000e-01,
1.796742000000000e-01,
1.971936000000000e-01,
2.155275000000000e-01,
2.346759000000000e-01,
2.546397000000000e-01,
2.754189000000000e-01,
2.970126000000000e-01,
3.194208000000000e-01,
3.426435000000000e-01,
3.666816000000000e-01,
3.915342000000000e-01,
4.172022000000000e-01,
4.436847000000000e-01,
4.709826000000000e-01,
4.990950000000000e-01,
5.280218999999999e-01,
5.577633000000000e-01,
5.883201000000000e-01,
6.196923000000001e-01,
6.518790000000000e-01,
6.848802000000001e-01,
7.186959000000001e-01,
7.533270000000001e-01,
7.887735000000000e-01,
8.250336000000000e-01,
8.621100000000000e-01,
9.000000000000000e-01,
1.000000000000000e+00,
};
check_is_close(y, expect);
}
BOOST_AUTO_TEST_SUITE_END ()

View File

@ -22,10 +22,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_ECLPROPERTYUNITCONVERSION

View File

@ -21,10 +21,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_ECLPROPTABLE

View File

@ -22,10 +22,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_ECLPVTCOMMON_UNITCONV

View File

@ -22,10 +22,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_REGION_MAPPING

View File

@ -21,10 +21,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_ECL1DINTERPOLATION

View File

@ -22,10 +22,6 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_UNIT_HANDLING

View File

@ -15,7 +15,7 @@
###########################################################################
# Mandatory call to project
project(opm-flowdiagnostics CXX)
project(opm-flowdiagnostics C CXX)
cmake_minimum_required (VERSION 2.8)

View File

@ -5,8 +5,8 @@
Module: opm-flowdiagnostics
Description: Open Porous Media Initiative flow diagnostics
Version: 2016.10-pre
Label: 2016.10-pre
Version: 2018.10-pre
Label: 2018.10-pre
Maintainer: opm@opm-project.org
MaintainerName: OPM community
Url: http://opm-project.org

View File

@ -0,0 +1,19 @@
# -*- mode: cmake; tab-width: 2; indent-tabs-mode: t; truncate-lines: t; compile-command: "cmake -Wdev" -*-
# vim: set filetype=cmake autoindent tabstop=2 shiftwidth=2 noexpandtab softtabstop=2 nowrap:
# defines that must be present in config.h for our headers
set (opm-flowdiagnostics_CONFIG_VAR
)
# dependencies
set (opm-flowdiagnostics_DEPS
# compile with C99 support if available
"C99"
# compile with C++0x/11 support if available
"CXX11Features REQUIRED"
"Boost 1.44.0
COMPONENTS unit_test_framework REQUIRED"
"opm-common REQUIRED"
)
find_package_deps(opm-flowdiagnostics)

View File

@ -18,13 +18,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE

View File

@ -20,10 +20,6 @@
#include <config.h>
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TEST_CELLSET

View File

@ -18,13 +18,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE

View File

@ -18,13 +18,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE

View File

@ -17,13 +17,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif // HAVE_DYNAMIC_BOOST_TEST
#define NVERBOSE

View File

@ -18,13 +18,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif // HAVE_DYNAMIC_BOOST_TEST
#define NVERBOSE

View File

@ -20,10 +20,6 @@
#include <config.h>
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE
#define BOOST_TEST_MODULE TarjanImplementationTest