UnitSystem: Add Support for PVT-M Unit Conventions

The PVT-M unit convention is essentially the same as the Metric
collection, except that pressure values are measured in atmospheres
rather than bars.
This commit is contained in:
Bård Skaflestad
2017-10-05 17:37:36 +02:00
parent 2c7d4dec41
commit e821f5534b
4 changed files with 220 additions and 1 deletions

View File

@@ -36,7 +36,8 @@ namespace Opm {
enum class UnitType {
UNIT_TYPE_METRIC = 0,
UNIT_TYPE_FIELD = 1,
UNIT_TYPE_LAB = 2
UNIT_TYPE_LAB = 2,
UNIT_TYPE_PVT_M = 3,
};
enum class measure : int {
@@ -96,6 +97,7 @@ namespace Opm {
static UnitSystem newMETRIC();
static UnitSystem newFIELD();
static UnitSystem newLAB();
static UnitSystem newPVT_M();
private:
Dimension parseFactor( const std::string& ) const;

View File

@@ -321,6 +321,31 @@ namespace Opm {
constexpr const double SurfaceTension = dyne/(centi*meter);
}
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);
}
}
#endif // OPM_UNITS_HEADER

View File

@@ -299,6 +299,93 @@ namespace {
"SCC/RCC", /* oil inverse formation volume factor */
"SCC/RCC", /* water inverse formation volume factor */
};
static const double to_pvt_m[] = {
1,
1 / PVT_M::Length,
1 / PVT_M::Time,
1 / PVT_M::Density,
1 / PVT_M::Pressure,
1 / PVT_M::AbsoluteTemperature,
1 / PVT_M::Temperature,
1 / PVT_M::Viscosity,
1 / PVT_M::Permeability,
1 / PVT_M::LiquidSurfaceVolume,
1 / PVT_M::GasSurfaceVolume,
1 / PVT_M::ReservoirVolume,
1 / ( PVT_M::LiquidSurfaceVolume / PVT_M::Time ),
1 / ( PVT_M::GasSurfaceVolume / PVT_M::Time ),
1 / ( PVT_M::ReservoirVolume / PVT_M::Time ),
1 / PVT_M::Transmissibility,
1 / PVT_M::Mass,
1 / (PVT_M::GasSurfaceVolume / PVT_M::LiquidSurfaceVolume), // Rs
1 / (PVT_M::LiquidSurfaceVolume / PVT_M::GasSurfaceVolume), // Rv
1, /* water cut */
1 / (PVT_M::ReservoirVolume / PVT_M::GasSurfaceVolume), /* Bg */
1 / (PVT_M::ReservoirVolume / PVT_M::LiquidSurfaceVolume), /* Bo */
1 / (PVT_M::ReservoirVolume / PVT_M::LiquidSurfaceVolume), /* Bw */
1 / (PVT_M::GasSurfaceVolume / PVT_M::ReservoirVolume), /* 1/Bg */
1 / (PVT_M::LiquidSurfaceVolume / PVT_M::ReservoirVolume), /* 1/Bo */
1 / (PVT_M::LiquidSurfaceVolume / PVT_M::ReservoirVolume), /* 1/Bw */
};
static const double from_pvt_m[] = {
1,
PVT_M::Length,
PVT_M::Time,
PVT_M::Density,
PVT_M::Pressure,
PVT_M::AbsoluteTemperature,
PVT_M::Temperature,
PVT_M::Viscosity,
PVT_M::Permeability,
PVT_M::LiquidSurfaceVolume,
PVT_M::GasSurfaceVolume,
PVT_M::ReservoirVolume,
PVT_M::LiquidSurfaceVolume / PVT_M::Time,
PVT_M::GasSurfaceVolume / PVT_M::Time,
PVT_M::ReservoirVolume / PVT_M::Time,
PVT_M::Transmissibility,
PVT_M::Mass,
PVT_M::GasSurfaceVolume / PVT_M::LiquidSurfaceVolume, // Rs
PVT_M::LiquidSurfaceVolume / PVT_M::GasSurfaceVolume, // Rv
1, /* water cut */
PVT_M::ReservoirVolume / PVT_M::GasSurfaceVolume, /* Bg */
PVT_M::ReservoirVolume / PVT_M::LiquidSurfaceVolume, /* Bo */
PVT_M::ReservoirVolume / PVT_M::LiquidSurfaceVolume, /* Bw */
PVT_M::GasSurfaceVolume / PVT_M::ReservoirVolume, /* 1/Bg */
PVT_M::LiquidSurfaceVolume / PVT_M::ReservoirVolume, /* 1/Bo */
PVT_M::LiquidSurfaceVolume / PVT_M::ReservoirVolume, /* 1/Bw */
};
static constexpr const char* pvt_m_names[] = {
"",
"M",
"DAY",
"KG/M3",
"ATM",
"K",
"C",
"CP",
"MD",
"SM3",
"SM3",
"RM3",
"SM3/DAY",
"SM3/DAY",
"RM3/DAY",
"CPR3/DAY/ATM",
"KG",
"SM3/SM3",
"SM3/SM3",
"SM3/SM3",
"RM3/SM3", /* gas formation volume factor */
"RM3/SM3", /* oil formation volume factor */
"RM3/SM3", /* water formation volume factor */
"SM3/RM3", /* gas inverse formation volume factor */
"SM3/RM3", /* oil inverse formation volume factor */
"SM3/RM3", /* water inverse formation volume factor */
};
}
UnitSystem::UnitSystem(const UnitType unit) :
@@ -323,6 +410,12 @@ namespace {
this->measure_table_to_si = from_lab;
this->unit_name_table = lab_names;
break;
case(UnitType::UNIT_TYPE_PVT_M):
m_name = "PVT-M";
this->measure_table_from_si = to_pvt_m;
this->measure_table_to_si = from_pvt_m;
this->unit_name_table = pvt_m_names;
break;
default:
//do nothing
break;
@@ -336,6 +429,7 @@ namespace {
case(ECL_METRIC_UNITS): return UnitSystem::UnitType::UNIT_TYPE_METRIC;
case(ECL_FIELD_UNITS): return UnitSystem::UnitType::UNIT_TYPE_FIELD;
case(ECL_LAB_UNITS): return UnitSystem::UnitType::UNIT_TYPE_LAB;
case(ECL_PVT_M_UNITS): return UnitSystem::UnitType::UNIT_TYPE_PVT_M;
default:
throw std::runtime_error("What has happened here?");
}
@@ -389,6 +483,7 @@ namespace {
case UnitType::UNIT_TYPE_METRIC: return ECL_METRIC_UNITS;
case UnitType::UNIT_TYPE_FIELD: return ECL_FIELD_UNITS;
case UnitType::UNIT_TYPE_LAB: return ECL_LAB_UNITS;
case UnitType::UNIT_TYPE_PVT_M: return ECL_PVT_M_UNITS;
default:
throw std::runtime_error("What has happened here?");
}
@@ -568,4 +663,32 @@ namespace {
return system;
}
UnitSystem UnitSystem::newPVT_M() {
UnitSystem system( UnitType::UNIT_TYPE_PVT_M );
system.addDimension("1" , 1.0);
system.addDimension("Pressure" , PVT_M::Pressure );
system.addDimension("Temperature", PVT_M::Temperature, PVT_M::TemperatureOffset);
system.addDimension("AbsoluteTemperature", PVT_M::AbsoluteTemperature);
system.addDimension("Length" , PVT_M::Length);
system.addDimension("Time" , PVT_M::Time );
system.addDimension("Mass" , PVT_M::Mass );
system.addDimension("Permeability", PVT_M::Permeability );
system.addDimension("Transmissibility", PVT_M::Transmissibility );
system.addDimension("GasDissolutionFactor", PVT_M::GasDissolutionFactor);
system.addDimension("OilDissolutionFactor", PVT_M::OilDissolutionFactor);
system.addDimension("LiquidSurfaceVolume", PVT_M::LiquidSurfaceVolume );
system.addDimension("GasSurfaceVolume" , PVT_M::GasSurfaceVolume );
system.addDimension("ReservoirVolume", PVT_M::ReservoirVolume );
system.addDimension("Density" , PVT_M::Density );
system.addDimension("PolymerDensity", PVT_M::PolymerDensity);
system.addDimension("Salinity", PVT_M::Salinity);
system.addDimension("Viscosity" , PVT_M::Viscosity);
system.addDimension("Timestep" , PVT_M::Timestep);
system.addDimension("SurfaceTension" , PVT_M::SurfaceTension);
system.addDimension("ContextDependent", std::numeric_limits<double>::quiet_NaN());
return system;
}
}

View File

@@ -282,3 +282,72 @@ BOOST_AUTO_TEST_CASE ( UnitConstants ) {
const double flux_m3py = convert::to(flux_SI, cubic(meter)/year);
BOOST_REQUIRE_CLOSE (flux_m3py, 1e4, 0.01);
}
BOOST_AUTO_TEST_CASE(PVT_M_UNITS)
{
using Meas = UnitSystem::measure;
auto pvt_m = UnitSystem::newPVT_M();
BOOST_CHECK( pvt_m.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_PVT_M );
BOOST_CHECK( pvt_m.getEclType() == ECL_PVT_M_UNITS );
// ----------------------------------------------------------------
// PVT-M -> SI
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::length , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::time , 1.0 ) , 86.400e3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::density , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::pressure , 1.0 ) , 101325.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::temperature_absolute , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::temperature , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::viscosity , 1.0 ) , 1.0e-3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::permeability , 1.0 ) , 9.869232667160129e-16 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::liquid_surface_volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::gas_surface_volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::liquid_surface_rate , 1.0 ) , 1.1574074074074073e-05 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::gas_surface_rate , 1.0 ) , 1.1574074074074073e-05 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::rate , 1.0 ) , 1.1574074074074073e-05 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::transmissibility , 1.0 ) , 1.142272299439830e-13 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::mass , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::gas_oil_ratio , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::oil_gas_ratio , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::water_cut , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::gas_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::oil_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::water_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::gas_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::oil_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.to_si( Meas::water_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
// ----------------------------------------------------------------
// SI -> PVT-M
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::length , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::time , 1.0 ) , 1.1574074074074073e-05 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::density , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::pressure , 1.0 ) , 9.869232667160129e-06 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::temperature_absolute , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::temperature , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::viscosity , 1.0 ) , 1.0e+3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::permeability , 1.0 ) , 1.01325e+15 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::liquid_surface_volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::gas_surface_volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::volume , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::liquid_surface_rate , 1.0 ) , 86.400e3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::gas_surface_rate , 1.0 ) , 86.400e3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::rate , 1.0 ) , 86.400e3 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::transmissibility , 1.0 ) , 8.75448e+12 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::mass , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::gas_oil_ratio , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::oil_gas_ratio , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::water_cut , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::gas_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::oil_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::water_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::gas_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::oil_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
BOOST_CHECK_CLOSE( pvt_m.from_si( Meas::water_inverse_formation_volume_factor , 1.0 ) , 1.0 , 1.0e-10 );
}