From a8b6047b1d7d541a7f459aa7ee33e03d002bc819 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 10 Oct 2016 15:41:19 +0200 Subject: [PATCH] fully move the units code from opm-core to opm-parser this fixes some annoying inconsistencies (e.g., the recently introduced 'dyne' unit was unavailable in the opm-core version) and gets rid of some compiler abiguity errors if 'using namespace Opm::details' was used by code inside the 'Opm' namespace. Since opm-parser is a hard dependency of opm-core, the only measure which must be taken by higher-level code is to include 'opm/parser/eclipse/Units/Units.hpp' instead of 'opm/parser/eclipse/Units/ConversionFactors.hpp' or 'opm/core/utility/Units.hpp'. Note that a potentially better location for this code would be opm-common, but this would break the Windows build of opm-parser. --- .../EclipseState/Grid/tests/ADDREGTests.cpp | 2 +- .../InitConfig/tests/InitConfigTest.cpp | 4 +- .../eclipse/EclipseState/Schedule/Tuning.cpp | 2 +- .../Schedule/tests/TuningTests.cpp | 2 +- .../EclipseState/Schedule/tests/WellTests.cpp | 2 +- .../tests/Eclipse3DPropertiesTests.cpp | 2 +- .../EclipseState/tests/EclipseStateTests.cpp | 2 +- .../eclipse/IntegrationTests/NNCTests.cpp | 2 +- .../eclipse/IntegrationTests/ParseDENSITY.cpp | 2 +- .../eclipse/IntegrationTests/ParsePORO.cpp | 2 +- .../ParseWellWithWildcards.cpp | 2 +- .../ScheduleCreateFromDeck.cpp | 2 +- .../TransMultIntegrationTests.cpp | 2 +- .../eclipse/Units/ConversionFactors.hpp | 272 -------------- opm/parser/eclipse/Units/UnitSystem.cpp | 2 +- opm/parser/eclipse/Units/Units.hpp | 335 ++++++++++++++++++ opm/parser/eclipse/Units/tests/UnitTests.cpp | 4 +- 17 files changed, 352 insertions(+), 289 deletions(-) delete mode 100644 opm/parser/eclipse/Units/ConversionFactors.hpp create mode 100644 opm/parser/eclipse/Units/Units.hpp diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/ADDREGTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/ADDREGTests.cpp index 98876c354..16bb2f4a8 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/ADDREGTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/ADDREGTests.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/opm/parser/eclipse/EclipseState/InitConfig/tests/InitConfigTest.cpp b/opm/parser/eclipse/EclipseState/InitConfig/tests/InitConfigTest.cpp index f6e05981d..b8015f85e 100644 --- a/opm/parser/eclipse/EclipseState/InitConfig/tests/InitConfigTest.cpp +++ b/opm/parser/eclipse/EclipseState/InitConfig/tests/InitConfigTest.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include using namespace Opm; @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE( EquilOperations ) { const auto& record = equil.getRecord( 0 ); BOOST_CHECK_CLOSE( 2469, record.datumDepth(), 1e-12 ); - BOOST_CHECK_CLOSE( 382.4 * details::unit::barsa, record.datumDepthPressure(), 1e-12 ); + BOOST_CHECK_CLOSE( 382.4 * unit::barsa, record.datumDepthPressure(), 1e-12 ); BOOST_CHECK_CLOSE( 1705.0, record.waterOilContactDepth(), 1e-12 ); BOOST_CHECK_CLOSE( 0.0, record.waterOilContactCapillaryPressure(), 1e-12 ); BOOST_CHECK_CLOSE( 500, record.gasOilContactDepth(), 1e-12 ); diff --git a/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp b/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp index b2f2ba11a..79ca402a2 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include namespace Opm { diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/TuningTests.cpp b/opm/parser/eclipse/EclipseState/Schedule/tests/TuningTests.cpp index fcce67fb3..8ddc05624 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/tests/TuningTests.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/TuningTests.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include using namespace Opm; diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/WellTests.cpp b/opm/parser/eclipse/EclipseState/Schedule/tests/WellTests.cpp index c47d463b6..12e09d224 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/tests/WellTests.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/WellTests.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include diff --git a/opm/parser/eclipse/EclipseState/tests/Eclipse3DPropertiesTests.cpp b/opm/parser/eclipse/EclipseState/tests/Eclipse3DPropertiesTests.cpp index 95b1ba431..cb5cdd5a7 100644 --- a/opm/parser/eclipse/EclipseState/tests/Eclipse3DPropertiesTests.cpp +++ b/opm/parser/eclipse/EclipseState/tests/Eclipse3DPropertiesTests.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include static Opm::DeckPtr createDeck() { const char *deckData = "RUNSPEC\n" diff --git a/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp b/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp index b81d92ca8..9b5012dd1 100644 --- a/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp +++ b/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp @@ -42,7 +42,7 @@ along with OPM. If not, see . #include #include #include -#include +#include #include #include #include diff --git a/opm/parser/eclipse/IntegrationTests/NNCTests.cpp b/opm/parser/eclipse/IntegrationTests/NNCTests.cpp index faae9f277..8debe5daa 100644 --- a/opm/parser/eclipse/IntegrationTests/NNCTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/NNCTests.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #define BOOST_TEST_MODULE NNCTests diff --git a/opm/parser/eclipse/IntegrationTests/ParseDENSITY.cpp b/opm/parser/eclipse/IntegrationTests/ParseDENSITY.cpp index 5b22941ae..cb9ed3189 100644 --- a/opm/parser/eclipse/IntegrationTests/ParseDENSITY.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParseDENSITY.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/opm/parser/eclipse/IntegrationTests/ParsePORO.cpp b/opm/parser/eclipse/IntegrationTests/ParsePORO.cpp index 382dc2923..cb8eee98f 100644 --- a/opm/parser/eclipse/IntegrationTests/ParsePORO.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParsePORO.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include diff --git a/opm/parser/eclipse/IntegrationTests/ParseWellWithWildcards.cpp b/opm/parser/eclipse/IntegrationTests/ParseWellWithWildcards.cpp index 75b1ef9bc..2935c4421 100644 --- a/opm/parser/eclipse/IntegrationTests/ParseWellWithWildcards.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParseWellWithWildcards.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include #include diff --git a/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp b/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp index 5dfa640e7..10c48a56d 100644 --- a/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp +++ b/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include using namespace Opm; diff --git a/opm/parser/eclipse/IntegrationTests/TransMultIntegrationTests.cpp b/opm/parser/eclipse/IntegrationTests/TransMultIntegrationTests.cpp index 6ffa19ddd..ceccc38b5 100644 --- a/opm/parser/eclipse/IntegrationTests/TransMultIntegrationTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/TransMultIntegrationTests.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include using namespace Opm; diff --git a/opm/parser/eclipse/Units/ConversionFactors.hpp b/opm/parser/eclipse/Units/ConversionFactors.hpp deleted file mode 100644 index 46b78fc3b..000000000 --- a/opm/parser/eclipse/Units/ConversionFactors.hpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - Copyright 2013 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 . -*/ - -#ifndef CONVERSION_FACTORS_HPP -#define CONVERSION_FACTORS_HPP - - -/** - 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 Opm { - - namespace details { - // Note: the following has been lifted from opm/core/utility/Units.hpp. - - 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; - /// @} - - // -------------------------------------------------------------- - // 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; - /// @} - } - - } // namespace details - - - namespace Metric { - using namespace details::prefix; - using namespace details::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); - } - - - namespace Field { - using namespace details::prefix; - using namespace details::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); - } - - - namespace Lab { - using namespace details::prefix; - using namespace details::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); - } - -} - -#endif diff --git a/opm/parser/eclipse/Units/UnitSystem.cpp b/opm/parser/eclipse/Units/UnitSystem.cpp index a2fa5790a..9f957e752 100644 --- a/opm/parser/eclipse/Units/UnitSystem.cpp +++ b/opm/parser/eclipse/Units/UnitSystem.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/opm/parser/eclipse/Units/Units.hpp b/opm/parser/eclipse/Units/Units.hpp new file mode 100644 index 000000000..6834d6fb9 --- /dev/null +++ b/opm/parser/eclipse/Units/Units.hpp @@ -0,0 +1,335 @@ +//=========================================================================== +// +// File: Units.hpp +// +// Created: Thu Jul 2 09:19:08 2009 +// +// Author(s): Halvor M Nilsen +// +// $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 . +*/ + +#ifndef OPM_UNITS_HEADER +#define OPM_UNITS_HEADER + +/** + 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 Opm { + 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; + /// @} + + // -------------------------------------------------------------- + // 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 std::vector p, 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 unit. + */ + constexpr double to(const double q, const double unit) + { + return q / unit; + } + } // namespace convert + + +#ifndef HAS_ATTRIBUTE_UNUSED + namespace detail { + // Some units are sometimes unused, and generate a (potentially) large number of warnings + // Adding them here silences these warnings, and should have no side-effects + constexpr double __attribute__((unused)) unused_units = stb + liter + barsa + psia + darcy; + } // namespace detail +#endif + } + + 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); + } + + + 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); + } + + + 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); + } + +} + +#endif // OPM_UNITS_HEADER diff --git a/opm/parser/eclipse/Units/tests/UnitTests.cpp b/opm/parser/eclipse/Units/tests/UnitTests.cpp index 4cf311dd2..a38c83dd7 100644 --- a/opm/parser/eclipse/Units/tests/UnitTests.cpp +++ b/opm/parser/eclipse/Units/tests/UnitTests.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(LabUnitConversions) { auto lab = std::unique_ptr( UnitSystem::newLAB() ); { - const auto furlong = 660*details::unit::feet; + const auto furlong = 660*unit::feet; BOOST_CHECK_CLOSE( 2.01168e4 , lab->from_si( Meas::length , furlong ) , 1.0e-10 ); BOOST_CHECK_CLOSE( furlong , lab->to_si( Meas::length , 2.01168e4 ) , 1.0e-10 ); }