From 8dc4adbe51d8fa83552524c44b85b5256c42ea3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Mon, 23 Aug 2010 09:23:09 +0000 Subject: [PATCH 001/113] Move solvers/common solvers/euler and solvers/mimetic to dune-porsol --- dune/porsol/common/linearInterpolation.hpp | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 dune/porsol/common/linearInterpolation.hpp diff --git a/dune/porsol/common/linearInterpolation.hpp b/dune/porsol/common/linearInterpolation.hpp new file mode 100644 index 00000000..830545f8 --- /dev/null +++ b/dune/porsol/common/linearInterpolation.hpp @@ -0,0 +1,90 @@ +//=========================================================================== +// +// File: linearInterpolation.hpp +// +// Created: Tue Sep 9 12:49:39 2008 +// +// Author(s): Atgeirr F Rasmussen +// +// $Date$ +// +// $Revision$ +// +//=========================================================================== + +/* + Copyright 2009, 2010 SINTEF ICT, Applied Mathematics. + Copyright 2009, 2010 Statoil ASA. + + This file is part of The Open Reservoir Simulator Project (OpenRS). + + OpenRS 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. + + OpenRS 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 OpenRS. If not, see . +*/ + +#ifndef OPENRS_LINEARINTERPOLATION_HEADER +#define OPENRS_LINEARINTERPOLATION_HEADER + + +#include +#include + +namespace Dune +{ + + /** Linear interpolation. + * Given an increasing vector xv of parameter values and + * a vector yv of point values of the same size, + * the function returns ... + */ + template + T linearInterpolation(const std::vector& xv, + const std::vector& yv, + double x) + { + std::vector::const_iterator lb = std::lower_bound(xv.begin(), xv.end(), x); + int lb_ix = lb - xv.begin(); + if (lb_ix == 0) { + return yv[0]; + } else if (lb_ix == int(xv.size())) { + return yv.back(); + } else { + double w = (x - xv[lb_ix - 1])/(xv[lb_ix] - xv[lb_ix - 1]); + return (1.0 - w)*yv[lb_ix - 1] + w*yv[lb_ix]; + } + } + + /// @brief + /// @todo Doc me! + /// @tparam + /// @param + /// @return + template + T linearInterpolationDerivative(const std::vector& xv, + const std::vector& yv, + double x) + { + double epsilon = 1e-4; // @@ Ad hoc, should choose based on xv. + double x_low = std::max(xv[0], x - epsilon); + double x_high = std::min(xv.back(), x + epsilon); + T low = linearInterpolation(xv, yv, x_low); + T high = linearInterpolation(xv, yv, x_high); + return (high - low)/(x_high - x_low); + } + + +} // namespace Dune + + + +#endif // OPENRS_LINEARINTERPOLATION_HEADER From df226cc2a4b0fc5505fc9dd1f898deda990abaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 8 Nov 2010 14:12:10 +0100 Subject: [PATCH 002/113] Created a new utility class, UniformTableLinear. --- dune/porsol/common/UniformTableLinear.hpp | 222 ++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 dune/porsol/common/UniformTableLinear.hpp diff --git a/dune/porsol/common/UniformTableLinear.hpp b/dune/porsol/common/UniformTableLinear.hpp new file mode 100644 index 00000000..5b416cbd --- /dev/null +++ b/dune/porsol/common/UniformTableLinear.hpp @@ -0,0 +1,222 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_UNIFORMTABLELINEAR_HEADER_INCLUDED +#define OPM_UNIFORMTABLELINEAR_HEADER_INCLUDED + +#include +#include +#include +#include + +#include +#include + +namespace Dune { + namespace utils { + + + /// @brief Exception used for domain errors. + struct OutsideDomainException : public std::exception {}; + + + /// @brief This class uses linear interpolation to compute the value + /// (and its derivative) of a function f sampled at uniform points. + /// @tparam T the range type of the function (should be an algebraic ring type) + template + class UniformTableLinear + { + public: + /// @brief Default constructor. + UniformTableLinear(); + + /// @brief Useful constructor. + /// @param xmin the x value corresponding to the first y value. + /// @param xmax the x value corresponding to the last y value. + /// @param y_values vector of range values. + UniformTableLinear(double xmin, + double xmax, + const std::vector& y_values); + + /// @brief Get the domain. + /// @return the domain as a pair of doubles. + std::pair domain(); + + /// @brief Rescale the domain. + /// @param new_domain the new domain as a pair of doubles. + void rescaleDomain(std::pair new_domain); + + /// @brief Evaluate the value at x. + /// @param x a domain value + /// @return f(x) + double operator()(const double x) const; + + /// @brief Evaluate the derivative at x. + /// @param x a domain value + /// @return f'(x) + double derivative(const double x) const; + + /// @brief Equality operator. + /// @param other another UniformTableLinear. + /// @return true if they are represented exactly alike. + bool operator==(const UniformTableLinear& other) const; + + /// @brief Policies for how to behave when trying to evaluate outside the domain. + enum RangePolicy {Throw = 0, ClosestValue = 1, Extrapolate = 2}; + + /// @brief Sets the behavioural policy for evaluation to the left of the domain. + /// @param rp the policy + void setLeftPolicy(RangePolicy rp); + + /// @brief Sets the behavioural policy for evaluation to the right of the domain. + /// @param rp the policy + void setRightPolicy(RangePolicy rp); + + protected: + double xmin_; + double xmax_; + double xdelta_; + std::vector y_values_; + RangePolicy left_; + RangePolicy right_; + }; + + + // Member implementations. + + template + inline + UniformTableLinear + ::UniformTableLinear() + : left_(ClosestValue), right_(ClosestValue) + { + } + + template + inline + UniformTableLinear + ::UniformTableLinear(double xmin, + double xmax, + const std::vector& y_values) + : xmin_(xmin), xmax_(xmax), y_values_(y_values), + left_(ClosestValue), right_(ClosestValue) + { + ASSERT(xmax > xmin); + ASSERT(y_values.size() > 1); + xdelta_ = (xmax - xmin)/(y_values.size() - 1); + } + + template + inline std::pair + UniformTableLinear + ::domain() + { + return std::make_pair(xmin_, xmax_); + } + + template + inline void + UniformTableLinear + ::rescaleDomain(std::pair new_domain) + { + xmin_ = new_domain.first; + xmax_ = new_domain.second; + xdelta_ = (xmax_ - xmin_)/(y_values_.size() - 1); + } + + template + inline double + UniformTableLinear + ::operator()(const double xparam) const + { + // Implements ClosestValue policy. + double x = std::min(xparam, xmax_); + x = std::max(x, xmin_); + + // Lookup is easy since we are uniform in x. + double pos = (x - xmin_)/xdelta_; + double posi = std::floor(pos); + int left = int(posi); + if (left == int(y_values_.size()) - 1) { + // We are at xmax_ + return y_values_.back(); + } + double w = pos - posi; + return (1.0 - w)*y_values_[left] + w*y_values_[left + 1]; + } + + template + inline double + UniformTableLinear + ::derivative(const double xparam) const + { + // Implements ClosestValue policy. + double x = std::min(xparam, xmax_); + x = std::max(x, xmin_); + + // Lookup is easy since we are uniform in x. + double pos = (x - xmin_)/xdelta_; + double posi = std::floor(pos); + int left = int(posi); + if (left == int(y_values_.size()) - 1) { + // We are at xmax_ + --left; + } + return (y_values_[left + 1] - y_values_[left])/xdelta_; + } + + + template + inline bool + UniformTableLinear + ::operator==(const UniformTableLinear& other) const + { + return xmin_ == other.xmin_ + && xdelta_ == other.xdelta_ + && y_values_ == other.y_values_ + && left_ == other.left_ + && right_ == other.right_; + } + + template + inline void + UniformTableLinear + ::setLeftPolicy(RangePolicy rp) + { + if (rp != ClosestValue) { + THROW("Only ClosestValue RangePolicy implemented."); + } + left_ = rp; + } + + template + inline void + UniformTableLinear + ::setRightPolicy(RangePolicy rp) + { + if (rp != ClosestValue) { + THROW("Only ClosestValue RangePolicy implemented."); + } + right_ = rp; + } + + } // namespace utils +} // namespace Dune + +#endif // OPM_UNIFORMTABLELINEAR_HEADER_INCLUDED From e8a9b6767be1cd284b70848f632f70707e0b427c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 10 Nov 2010 13:31:32 +0100 Subject: [PATCH 003/113] Implemented FluidMatrixInteractionBlackoil init(), kr() and a test prog. --- dune/porsol/blackoil/test/bo_fluid_test.cpp | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 dune/porsol/blackoil/test/bo_fluid_test.cpp diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/dune/porsol/blackoil/test/bo_fluid_test.cpp new file mode 100644 index 00000000..9b0cb23c --- /dev/null +++ b/dune/porsol/blackoil/test/bo_fluid_test.cpp @@ -0,0 +1,50 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ + + +#include +#include +#include + + +int main(int argc, char** argv) +{ + // Parameters. + Dune::parameter::ParameterGroup param(argc, argv); + + std::string ecl_file = param.get("filename"); + Dune::EclipseGridParser parser(ecl_file); + Opm::FluidMatrixInteractionBlackoilParams fluid_params; + fluid_params.init(parser); + typedef Opm::FluidMatrixInteractionBlackoil Law; + + + Dune::FieldVector s, kr; + const double temp = 300; // [K] + int num = 41; + for (int i = 0; i < num; ++i) { + s[Law::Aqua] = 0.0; + s[Law::Liquid] = double(i)/double(num - 1); + s[Law::Vapour] = 1.0 - s[Law::Aqua] - s[Law::Liquid]; + Law::kr(kr, fluid_params, s, temp); + std::cout.width(6); + std::cout.fill(' '); + std::cout << s[Law::Liquid] << " " << kr << '\n'; + } +} From 4f4e837a87b23dcbc5f1ab55da076a340e4f16b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 10 Nov 2010 13:31:32 +0100 Subject: [PATCH 004/113] Implemented FluidMatrixInteractionBlackoil init(), kr() and a test prog. --- dune/porsol/common/UniformTableLinear.hpp | 28 +++++++++- .../common/buildUniformMonotoneTable.hpp | 52 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 dune/porsol/common/buildUniformMonotoneTable.hpp diff --git a/dune/porsol/common/UniformTableLinear.hpp b/dune/porsol/common/UniformTableLinear.hpp index 5b416cbd..8aa42d6b 100644 --- a/dune/porsol/common/UniformTableLinear.hpp +++ b/dune/porsol/common/UniformTableLinear.hpp @@ -46,7 +46,7 @@ namespace Dune { /// @brief Default constructor. UniformTableLinear(); - /// @brief Useful constructor. + /// @brief Construct from vector of y-values. /// @param xmin the x value corresponding to the first y value. /// @param xmax the x value corresponding to the last y value. /// @param y_values vector of range values. @@ -54,6 +54,16 @@ namespace Dune { double xmax, const std::vector& y_values); + /// @brief Construct from array of y-values. + /// @param xmin the x value corresponding to the first y value. + /// @param xmax the x value corresponding to the last y value. + /// @param y_values array of range values. + /// @param num_y_values the number of values in y_values. + UniformTableLinear(double xmin, + double xmax, + const T* y_values, + int num_y_values); + /// @brief Get the domain. /// @return the domain as a pair of doubles. std::pair domain(); @@ -122,6 +132,22 @@ namespace Dune { xdelta_ = (xmax - xmin)/(y_values.size() - 1); } + template + inline + UniformTableLinear + ::UniformTableLinear(double xmin, + double xmax, + const T* y_values, + int num_y_values) + : xmin_(xmin), xmax_(xmax), + y_values_(y_values, y_values + num_y_values), + left_(ClosestValue), right_(ClosestValue) + { + ASSERT(xmax > xmin); + ASSERT(y_values_.size() > 1); + xdelta_ = (xmax - xmin)/(y_values_.size() - 1); + } + template inline std::pair UniformTableLinear diff --git a/dune/porsol/common/buildUniformMonotoneTable.hpp b/dune/porsol/common/buildUniformMonotoneTable.hpp new file mode 100644 index 00000000..03c060be --- /dev/null +++ b/dune/porsol/common/buildUniformMonotoneTable.hpp @@ -0,0 +1,52 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_BUILDUNIFORMMONOTONETABLE_HEADER_INCLUDED +#define OPM_BUILDUNIFORMMONOTONETABLE_HEADER_INCLUDED + +#include +#include + +namespace Dune { + namespace utils { + + template + void buildUniformMonotoneTable(const std::vector& xv, + const std::vector& yv, + const int samples, + UniformTableLinear& table) + { + MonotCubicInterpolator interp(xv, yv); + std::vector uniform_yv(samples); + double xmin = xv[0]; + double xmax = xv.back(); + for (int i = 0; i < samples; ++i) { + double w = double(i)/double(samples - 1); + double x = (1.0 - w)*xmin + w*xmax; + uniform_yv[i] = interp(x); + } + table = UniformTableLinear(xmin, xmax, uniform_yv); + } + + } // namespace utils +} // namespace Dune + + + +#endif // OPM_BUILDUNIFORMMONOTONETABLE_HEADER_INCLUDED From 99e398a826825ebbf3433a5492abc58e563909e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 11 Nov 2010 15:18:18 +0100 Subject: [PATCH 005/113] Added a fluid system class. --- dune/porsol/blackoil/test/bo_fluid_test.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/dune/porsol/blackoil/test/bo_fluid_test.cpp index 9b0cb23c..ed848d9c 100644 --- a/dune/porsol/blackoil/test/bo_fluid_test.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_test.cpp @@ -19,6 +19,7 @@ #include +#include #include #include @@ -28,13 +29,14 @@ int main(int argc, char** argv) // Parameters. Dune::parameter::ParameterGroup param(argc, argv); + // Parser. std::string ecl_file = param.get("filename"); Dune::EclipseGridParser parser(ecl_file); + + // Test the FluidMatrixInteractionBlackoil class. Opm::FluidMatrixInteractionBlackoilParams fluid_params; fluid_params.init(parser); typedef Opm::FluidMatrixInteractionBlackoil Law; - - Dune::FieldVector s, kr; const double temp = 300; // [K] int num = 41; @@ -47,4 +49,8 @@ int main(int argc, char** argv) std::cout.fill(' '); std::cout << s[Law::Liquid] << " " << kr << '\n'; } + + // Test the FluidSystemBlackoil class. + Opm::FluidSystemBlackoil<> fluid_system; + fluid_system.init(parser); } From 45bf24c9b1f100961d9bbbfb72f00cafe4eb3c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:18:27 +0100 Subject: [PATCH 006/113] Added lots of stuff originally from the samcode repository. --- .../blackoil/fluid/BlackoilComponent.hpp | 165 ++++++++++++ dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 19 ++ dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 66 +++++ .../fluid/FluidMiscibilityThreePhase.cpp | 242 +++++++++++++++++ .../fluid/FluidMiscibilityThreePhase.hpp | 78 ++++++ .../blackoil/fluid/FluidStateBlackoil.hpp | 244 ++++++++++++++++++ dune/porsol/blackoil/fluid/Makefile.am | 11 + .../porsol/blackoil/fluid/MiscibilityDead.cpp | 96 +++++++ .../porsol/blackoil/fluid/MiscibilityDead.hpp | 47 ++++ .../blackoil/fluid/MiscibilityLiveGas.cpp | 200 ++++++++++++++ .../blackoil/fluid/MiscibilityLiveGas.hpp | 51 ++++ .../blackoil/fluid/MiscibilityLiveOil.cpp | 203 +++++++++++++++ .../blackoil/fluid/MiscibilityLiveOil.hpp | 51 ++++ .../blackoil/fluid/MiscibilityProps.cpp | 34 +++ .../blackoil/fluid/MiscibilityProps.hpp | 46 ++++ .../blackoil/fluid/MiscibilityWater.hpp | 81 ++++++ 16 files changed, 1634 insertions(+) create mode 100644 dune/porsol/blackoil/fluid/BlackoilComponent.hpp create mode 100644 dune/porsol/blackoil/fluid/BlackoilPVT.cpp create mode 100644 dune/porsol/blackoil/fluid/BlackoilPVT.hpp create mode 100644 dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp create mode 100644 dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp create mode 100644 dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp create mode 100644 dune/porsol/blackoil/fluid/Makefile.am create mode 100644 dune/porsol/blackoil/fluid/MiscibilityDead.cpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityDead.hpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityProps.cpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityProps.hpp create mode 100644 dune/porsol/blackoil/fluid/MiscibilityWater.hpp diff --git a/dune/porsol/blackoil/fluid/BlackoilComponent.hpp b/dune/porsol/blackoil/fluid/BlackoilComponent.hpp new file mode 100644 index 00000000..61294a68 --- /dev/null +++ b/dune/porsol/blackoil/fluid/BlackoilComponent.hpp @@ -0,0 +1,165 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_BLACKOILCOMPONENT_HEADER_INCLUDED +#define OPM_BLACKOILCOMPONENT_HEADER_INCLUDED + + +#include + +namespace Dumux +{ + +/*! + * \ingroup Components + + * \brief + * A component class for the black oil model, intended to be used + * for all three components. + * + * \tparam Scalar The type used for scalar values + */ +template +class BlackoilComponent +{ +public: + /*! + * \brief A human readable name for the component. + */ + static const char *name() + { + return "BlackoilComponent"; + } + + /*! + * \brief The molar mass in [kg] of the component. + */ + static Scalar molarMass() + { DUNE_THROW(Dune::NotImplemented, "Component::molarMass()"); } + + /*! + * \brief Returns the critical temperature in [K] of the component. + */ + static Scalar criticalTemperature() + { DUNE_THROW(Dune::NotImplemented, "Component::criticalTemperature()"); } + + /*! + * \brief Returns the critical pressure in [Pa] of the component. + */ + static Scalar criticalPressure() + { DUNE_THROW(Dune::NotImplemented, "Component::criticalPressure()"); } + + /*! + * \brief Returns the temperature in [K] at the component's triple point. + */ + static Scalar tripleTemperature() + { DUNE_THROW(Dune::NotImplemented, "Component::tripleTemperature()"); } + + /*! + * \brief Returns the pressure in [Pa] at the component's triple point. + */ + static Scalar triplePressure() + { DUNE_THROW(Dune::NotImplemented, "Component::triplePressure()"); } + + /*! + * \brief The vapor pressure in [Pa] of the component at a given + * temperature in [K]. + * + * \param T temperature of the component in [K] + */ + static Scalar vaporPressure(Scalar T) + { DUNE_THROW(Dune::NotImplemented, "Component::vaporPressure()"); } + + /*! + * \brief The density in [kg/m^3] of the component at a given pressure in [Pa] and temperature in [K]. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static Scalar gasDensity(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::density()"); } + + /*! + * \brief The density [kg/m^3] of the liquid component at a given pressure in [Pa] and temperature in [K]. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static Scalar liquidDensity(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::density()"); } + + /*! + * \brief Specific enthalpy [J/kg] of the pure component in gas. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static const Scalar gasEnthalpy(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::gasEnthalpy()"); } + + /*! + * \brief Specific enthalpy [J/kg] of the pure component in liquid. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static const Scalar liquidEnthalpy(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::liquidEnthalpy()"); } + + /*! + * \brief Specific internal energy [J/kg] of the pure component in gas. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static const Scalar gasInternalEnergy(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::gasInternalEnergy()"); } + + /*! + * \brief Specific internal energy [J/kg] of pure the pure component in liquid. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static const Scalar liquidInternalEnergy(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::liquidInternalEnergy()"); } + + /*! + * \brief The dynamic viscosity [Pa*s] of the pure component at a given pressure in [Pa] and temperature in [K]. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static Scalar gasViscosity(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::gasViscosity()"); } + + /*! + * \brief The dynamic liquid viscosity [Pa*s] of the pure component. + * + * \param temperature temperature of component in [K] + * \param pressure pressure of component in [Pa] + */ + static Scalar liquidViscosity(Scalar temperature, Scalar pressure) + { DUNE_THROW(Dune::NotImplemented, "Component::liquidViscosity()"); } + +}; + +} // end namepace + +#endif // OPM_BLACKOILCOMPONENT_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp new file mode 100644 index 00000000..aa42e90e --- /dev/null +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -0,0 +1,19 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ + diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp new file mode 100644 index 00000000..698daa0f --- /dev/null +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -0,0 +1,66 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_BLACKOILPVT_HEADER_INCLUDED +#define OPM_BLACKOILPVT_HEADER_INCLUDED + + +#include +#include +#include "MiscibilityProps.hpp" + +namespace Opm +{ + class BlackoilPVT + { + public: + typedef MiscibilityProps::surfvol_t surfvol_t; + + enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + + void init(const Dune::EclipseGridParser& ep); + + double getViscosity(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + surfvol_t getMobilities(double press, const surfvol_t& sat, const surfvol_t& surfvol) const; + surfvol_t surfaceDensities() const; + double B (double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double dBdp(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double R (double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double dRdp(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + + + private: + int region_number_; + const MiscibilityProps& propsForPhase(PhaseNames phase) const; + + boost::scoped_ptr water_props_; + boost::scoped_ptr oil_props_; + boost::scoped_ptr gas_props_; + surfvol_t densities_; + }; + +} + + +#endif // OPM_BLACKOILPVT_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp new file mode 100644 index 00000000..a25f0dce --- /dev/null +++ b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp @@ -0,0 +1,242 @@ +//=========================================================================== +// +// File: FluidMiscibilityThreePhase.cpp +// +// Created: Wed Feb 10 09:25:57 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#include "FluidMiscibilityThreePhase.hpp" +#include +#include "MiscibilityDead.hpp" +#include "MiscibilityLiveOil.hpp" +#include "MiscibilityLiveGas.hpp" +#include "MiscibilityWater.hpp" +#include +#include + +using namespace Dune; + +namespace samcode +{ + + + void FluidMiscibilityThreePhase::init(const std::string& pvt_filename) + { + typedef std::vector > > table_t; + region_number_ = 0; + Dune::EclipseGridParser eclipse_props(pvt_filename); + + // Surface densities. Accounting for different orders in eclipse and our code. + if (eclipse_props.hasField("DENSITY")) { + const int region_number = 0; + enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; + const std::vector > d_tmp = + eclipse_props.getDENSITY().densities_; + densities_[Aqua] = d_tmp[region_number][ECL_water]; + densities_[Liquid] = d_tmp[region_number][ECL_oil]; + densities_[Vapour] = d_tmp[region_number][ECL_gas]; + } else { + THROW("DENSITY not defined"); + } + + // Water PVT + if (eclipse_props.hasField("PVTW")) { + water_props_.reset(new MiscibilityWater(eclipse_props.getPVTW().pvtw_)); + } else { + water_props_.reset(new MiscibilityWater(3e-4)); // Default is 0.3 cP. + } + + // Oil PVT + if (eclipse_props.hasField("PVDO")) { + oil_props_.reset(new MiscibilityDead(eclipse_props.getPVDO().pvdo_)); + } else if (eclipse_props.hasField("PVTO")) { + oil_props_.reset(new MiscibilityLiveOil(eclipse_props.getPVTO().pvto_)); + } else { + THROW("File " << pvt_filename << " is missing PVDO and PVTO\n"); + } + + // Gas PVT + if (eclipse_props.hasField("PVDG")) { + gas_props_.reset(new MiscibilityDead(eclipse_props.getPVDG().pvdg_)); + } else if (eclipse_props.hasField("PVTG")) { + gas_props_.reset(new MiscibilityLiveGas(eclipse_props.getPVTG().pvtg_)); + } else { + THROW("File " << pvt_filename << " is missing PVDG and PVTG\n"); + } + + //SWOF + if (eclipse_props.hasField("SWOF")) { + swof_ = eclipse_props.getSWOF().swof_; + } + + //SGOF + if (eclipse_props.hasField("SGOF")) { + sgof_ = eclipse_props.getSGOF().sgof_; + } + + } + FluidMiscibilityThreePhase::surfvol_t FluidMiscibilityThreePhase::surfaceDensities() const + { + return densities_; + } + + double FluidMiscibilityThreePhase::getViscosity(double press, const surfvol_t& surfvol, PhaseNames phase) const + { + return propsForPhase(phase).getViscosity(region_number_, press, surfvol); + } + + FluidMiscibilityThreePhase::surfvol_t + FluidMiscibilityThreePhase::getMobilities(double press, const surfvol_t& sat, + const surfvol_t& surfvol) const + { + if (swof_.empty() || sgof_.empty()) { + THROW("The SWOF and SGOF keywords were not given, cannot compute mobilities. Try tracer_flow=true."); + } + surfvol_t mobilities; + double sw = sat[Aqua]; + double sg = sat[Vapour]; + mobilities[Aqua] = krw(sw)/getViscosity(press, surfvol, Aqua); + mobilities[Liquid] = krow(sw)*krog(sg)/getViscosity(press, surfvol, Liquid); + mobilities[Vapour] = krg(sg)/getViscosity(press, surfvol, Vapour); + return mobilities; + } + + double FluidMiscibilityThreePhase::B(double press, const surfvol_t& surfvol, PhaseNames phase) const + { + return propsForPhase(phase).B(region_number_, press, surfvol); + } + + double FluidMiscibilityThreePhase::dBdp(double press, const surfvol_t& surfvol, PhaseNames phase) const + { + return propsForPhase(phase).dBdp(region_number_, press, surfvol); + } + + double FluidMiscibilityThreePhase::R(double press, const surfvol_t& surfvol, PhaseNames phase) const + { + return propsForPhase(phase).R(region_number_, press, surfvol); + } + + double FluidMiscibilityThreePhase::dRdp(double press, const surfvol_t& surfvol, PhaseNames phase) const + { + return propsForPhase(phase).dRdp(region_number_, press, surfvol); + } + + const MiscibilityProps& FluidMiscibilityThreePhase::propsForPhase(PhaseNames phase) const + { + switch (phase) { + case Aqua: + return *water_props_; + case Liquid: + return *oil_props_; + case Vapour: + return *gas_props_; + default: + THROW("Unknown phase accessed: " << phase); + } + } + + // Stone's first model(Modified) + double FluidMiscibilityThreePhase::kro(double sw, double sg) const + { + double so = 1.0-sw-sg; + double fw = krow(sw); + double fg = krog(sg); + return so*fw*fg; + } + + // kro partial derivative Sw + double FluidMiscibilityThreePhase::dkro_dsw(double sw, double sg) const + { + double so = 1.0-sw-sg; + double fw = krow(sw); + double fg = krog(sg); + double fwder = dkrow_dsw(sw); + return fg*(-fw + so*fwder); + } + + // kro partial derivative Sg + double FluidMiscibilityThreePhase::dkro_dsg(double sw, double sg) const + { + double so = 1.0-sw-sg; + double fw = krow(sw); + double fg = krog(sg); + double fgder = dkrog_dsg(sg); + return fw*(-fg + so*fgder); + } + + // kro partial derivatives + void FluidMiscibilityThreePhase::dkro(double sw, double sg, double& dkro_dsw, + double& dkro_dsg) const + { + double so = 1.0-sw-sg; + double fw = krow(sw); + double fg = krog(sg); + double fwder = dkrow_dsw(sw); + double fgder = dkrog_dsg(sg); + dkro_dsw = fg*(-fw + so*fwder); + dkro_dsg = fw*(-fg + so*fgder); + } + + // Water relative permeability + double FluidMiscibilityThreePhase::krw (double sw) const + { + return linearInterpolation(swof_[region_number_][0], + swof_[region_number_][1], sw); + } + + // Oil relative permeability + double FluidMiscibilityThreePhase::krow (double sw) const + { + return linearInterpolation(swof_[region_number_][0], + swof_[region_number_][2], sw); + } + + // krow derivative + double FluidMiscibilityThreePhase::dkrow_dsw(double sw) const + { + return linearInterpolDerivative(swof_[region_number_][0], + swof_[region_number_][2], sw); + } + + // Water-oil capillary pressure + double FluidMiscibilityThreePhase::Pcow (double sw) const + { + return linearInterpolation(swof_[region_number_][0], + swof_[region_number_][3], sw); + } + + // Gas relative permeability + double FluidMiscibilityThreePhase::krg (double sg) const + { + return linearInterpolation(sgof_[region_number_][0], + sgof_[region_number_][1], sg); + } + + // Oil relative permeability + double FluidMiscibilityThreePhase::krog (double sg) const + { + return linearInterpolation(sgof_[region_number_][0], + sgof_[region_number_][2], sg); + } + + // krog derivative + double FluidMiscibilityThreePhase::dkrog_dsg(double sg) const + { + return linearInterpolDerivative(sgof_[region_number_][0], + sgof_[region_number_][2], sg); + } + + // Oil-gas capillary pressure + double FluidMiscibilityThreePhase::Pcog(double sg) const + { + return linearInterpolation(sgof_[region_number_][0], + sgof_[region_number_][3], sg); + } + + +} // namespace samcode diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp new file mode 100644 index 00000000..0b0243a0 --- /dev/null +++ b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp @@ -0,0 +1,78 @@ +//=========================================================================== +// +// File: FluidMiscibilityThreePhase.hpp +// +// Created: Thu Feb 11 10:35:05 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#ifndef SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER +#define SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER + + /** Temporary class for testing Miscibility* classes + * Detailed description. + */ +#include +#include +#include "MiscibilityProps.hpp" + +namespace samcode +{ + class FluidMiscibilityThreePhase + { + public: + typedef MiscibilityProps::surfvol_t surfvol_t; + + enum PhaseNames { Aqua = 0, Liquid = 1, Vapour = 2 }; + + FluidMiscibilityThreePhase(){} + ~FluidMiscibilityThreePhase(){} + void init(const std::string& pvt_filename); + + double getViscosity(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + surfvol_t getMobilities(double press, const surfvol_t& sat, const surfvol_t& surfvol) const; + surfvol_t surfaceDensities() const; + double B (double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double dBdp(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double R (double press, const surfvol_t& surfvol, + PhaseNames phase) const; + double dRdp(double press, const surfvol_t& surfvol, + PhaseNames phase) const; + + + private: + int region_number_; + const MiscibilityProps& propsForPhase(PhaseNames phase) const; + double kro(double sw, double sg) const; // Stone's first model(Modified) + double dkro_dsw(double sw, double sg) const; // kro partial derivative dSw + double dkro_dsg(double sw, double sg) const; // kro partial derivative dSg + void dkro (double sw, double sg, // kro partial derivatives. dSw and dSg + double& dkro_dsw, double& dkro_dsg) const; + double krw (double sw) const; // Water relative permeability + double krow (double sw) const; // Oil relative permeability + double dkrow_dsw (double sw) const; // krow derivative + double Pcow (double sw) const; // Water-oil capillary pressure + double krg (double sg) const; // Gas relative permeability + double krog (double sg) const; // Oil relative permeability + double dkrog_dsg(double sg) const; // krog derivative + double Pcog (double sg) const; // Oil-gas capillary pressure + + boost::scoped_ptr water_props_; + boost::scoped_ptr oil_props_; + boost::scoped_ptr gas_props_; + surfvol_t densities_; + std::vector > > sgof_; // Gas/Oil saturation + std::vector > > swof_; // Water/Oil saturation + }; + +} + +#endif // SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER + diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp new file mode 100644 index 00000000..7197b7e8 --- /dev/null +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -0,0 +1,244 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_FLUIDSTATEBLACKOIL_HEADER_INCLUDED +#define OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED + +namespace Opm +{ +/*! + * \brief Calcultes the phase state from the primary variables in the + * blackoil model. + */ +class FluidStateBlackoil +{ +public: + enum { numPhases = 3 }; + enum { numComponents = 3}; + + typedef int FluidSystem; // TODO + typedef int PrimaryVars; // TODO + typedef double Scalar; + typedef FluidMatrixInteractionBlackoil MaterialLaw; + typedef typename MaterialLaw::Params MaterialLawParams; + + /*! + * \brief Update the phase state from the primary variables. + */ + void update(const PrimaryVariables &primaryVars, + const MaterialLawParams &pcParams, + Scalar temperature) + { + // calculate the temperature + temperature_ = temperature; + + // calculate the saturations + saturation_[numPhases - 1] = 1.0; + for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) { + saturation_[phaseIdx] = primaryVars[S0Idx + phaseIdx]; + saturation_[numPhases - 1] -= saturation_[phaseIdx]; + } + + // let the material law calculate the capillary pressures + MaterialLaw::pC(phasePressure_, + pcParams, + saturation_, + temperature_); + + // convert to phase pressures + Scalar sumPc = 0; + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + sumPc += phasePressure_[phaseIdx]; + phasePressure_[phaseIdx] = primaryVars[p0Idx] - sumPc; + } + + updateComposition_(primaryVars); + } + +private: + void updateComposition_(const PrimaryVariables &primaryVars) + { + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + meanMolarMass_[phaseIdx] = 0; + } + + // extract the mole fractions in both phases + Scalar sumFuga = 0; + for (int compIdx = 0; compIdx < numComponents; ++compIdx) { + fugacity_[compIdx] = primaryVars[fug0Idx + compIdx]; + Valgrind::CheckDefined(fugacity_[compIdx]); + sumFuga += fugacity_[compIdx]; + + // convert the fugacities into mole fractions + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + moleFrac_[phaseIdx][compIdx] = + fugacity_[compIdx] / + FluidSystem::activityCoeff(phaseIdx, + compIdx, + temperature_, + phasePressure(phaseIdx), + *this); + Valgrind::CheckDefined(moleFrac_[phaseIdx][compIdx]); + + // update the mean molar mass of each phase + meanMolarMass_[phaseIdx] + += FluidSystem::molarMass(compIdx)*moleFrac_[phaseIdx][compIdx]; + } + } + + // make sure that the primary variables do not represent an + // unphysical state! + if (sumFuga < 1e-30) { + DUNE_THROW(NumericalProblem, + "Sum of component fugacities is too small: " << sumFuga); + } + + // calculate the total concentration of each phase + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + // make sure that the mean molar mass within a phase is + // not "way off" + if (std::abs(meanMolarMass_[phaseIdx]) < 1e-30) + DUNE_THROW(NumericalProblem, + "Mean molar mass of phase " + << phaseIdx + << " is too small (" + << meanMolarMass_[phaseIdx] + << ")\n" << primaryVars); + + // calculate the total concentration of the phase + phaseConcentration_[phaseIdx] = + FluidSystem::phaseDensity(phaseIdx, + temperature(), + phasePressure(phaseIdx), + *this) + / + meanMolarMass_[phaseIdx]; + } + + Valgrind::CheckDefined(fugacity_); + Valgrind::CheckDefined(moleFrac_); + Valgrind::CheckDefined(phaseConcentration_); + Valgrind::CheckDefined(meanMolarMass_); + Valgrind::CheckDefined(temperature_); + Valgrind::CheckDefined(phasePressure_); + Valgrind::CheckDefined(saturation_); + } + +public: + /*! + * \brief Returns the saturation of a phase. + */ + Scalar saturation(int phaseIdx) const + { return saturation_[phaseIdx]; } + + /*! + * \brief Returns a vector of all phase saturations. + */ + const Scalar *saturations() const + { return saturation_; } + + /*! + * \brief Returns the molar fraction of a component in a fluid phase. + */ + Scalar moleFrac(int phaseIdx, int compIdx) const + { return moleFrac_[phaseIdx][compIdx]; } + + /*! + * \brief Returns the total concentration of a phase [mol / m^3]. + * + * This is equivalent to the sum of all component concentrations. + */ + Scalar phaseConcentration(int phaseIdx) const + { return phaseConcentration_[phaseIdx]; }; + + /*! + * \brief Returns the concentration of a component in a phase [mol / m^3]. + */ + Scalar concentration(int phaseIdx, int compIdx) const + { return moleFrac_[phaseIdx][compIdx]*phaseConcentration_[phaseIdx]; }; + + /*! + * \brief Returns the mass fraction of a component in a phase. + */ + Scalar massFrac(int phaseIdx, int compIdx) const + { + return + moleFrac_[phaseIdx][compIdx]* + FluidSystem::molarMass(compIdx) + / + meanMolarMass_[phaseIdx]; + } + + /*! + * \brief Returns the density of a phase [kg / m^3]. + */ + Scalar density(int phaseIdx) const + { return phaseConcentration_[phaseIdx]*meanMolarMass_[phaseIdx]; } + + /*! + * \brief Returns mean molar mass of a phase [kg / mol]. + * + * This is equivalent to the sum of all component molar masses + * weighted by their respective mole fraction. + */ + Scalar meanMolarMass(int phaseIdx) const + { return meanMolarMass_[phaseIdx]; }; + + /*! + * \brief Returns the fugacity of a component [Pa]. + */ + Scalar fugacity(int compIdx) const + { return fugacity_[compIdx]; } + + /*! + * \brief Returns the pressure of a fluid phase [Pa]. + */ + Scalar phasePressure(int phaseIdx) const + { return phasePressure_[phaseIdx]; } + + /*! + * \brief Returns the capillary pressure [Pa] + */ + Scalar capillaryPressure(int phaseIdx) const + { return phasePressure_[0] - phasePressure_[phaseIdx]; } + + /*! + * \brief Returns the temperature of the fluids [K]. + * + * Note that we assume thermodynamic equilibrium, so all fluids + * and the rock matrix exhibit the same temperature. + */ + Scalar temperature() const + { return temperature_; }; + +public: + Scalar fugacity_[numComponents]; + Scalar moleFrac_[numPhases][numComponents]; + Scalar phaseConcentration_[numPhases]; + Scalar meanMolarMass_[numPhases]; + Scalar phasePressure_[numPhases]; + Scalar saturation_[numPhases]; + Scalar temperature_; +}; + +} // end namespace Opm + + +#endif // OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/Makefile.am b/dune/porsol/blackoil/fluid/Makefile.am new file mode 100644 index 00000000..efec558f --- /dev/null +++ b/dune/porsol/blackoil/fluid/Makefile.am @@ -0,0 +1,11 @@ +noinst_LTLIBRARIES = libblackoilfluid_noinst.la + +libblackoilfluid_noinst_la_SOURCES = \ + BlackoilPVT.cpp \ + MiscibilityDead.cpp \ + MiscibilityLiveGas.cpp \ + MiscibilityLiveOil.cpp \ + MiscibilityProps.cpp + + +include $(top_srcdir)/am/global-rules diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp new file mode 100644 index 00000000..fca1a1b3 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -0,0 +1,96 @@ +//=========================================================================== +// +// File: MiscibilityDead.cpp +// +// Created: Wed Feb 10 09:06:04 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#include +#include "MiscibilityDead.hpp" +#include +#include + +using namespace std; +using namespace Dune; + +namespace samcode +{ + + //------------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------------- + + /// Constructor + MiscibilityDead::MiscibilityDead(const table_t& pvd_table) + : pvdx_(pvd_table) + { + const int region_number = 0; + if (pvd_table.size() != 1) { + THROW("More than one PVT-region"); + } + // Convert units + const double bar = 1e5; + const double VISCOSITY_UNIT = 1e-3; + const int sz = pvdx_[region_number][0].size(); + for (int i=0; i +// +// Revision: $Id$ +// +//=========================================================================== + +#ifndef SINTEF_MISCIBILITYDEAD_HEADER +#define SINTEF_MISCIBILITYDEAD_HEADER + +/** Class for immiscible dead oil and dry gas. + * Detailed description. + */ + +#include "MiscibilityProps.hpp" + +namespace samcode +{ + class MiscibilityDead : public MiscibilityProps + { + public: + typedef std::vector > > table_t; + + MiscibilityDead(const table_t& pvd_table); + virtual ~MiscibilityDead(); + + virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; + virtual double B(int region, double press, const surfvol_t& surfvol) const; + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; + virtual double R(int region, double press, const surfvol_t& surfvol) const; + virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; + + + private: + // PVT properties of dry gas or dead oil + table_t pvdx_; + }; + +} + +#endif // SINTEF_MISCIBILITYDEAD_HEADER + diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp new file mode 100644 index 00000000..b784523a --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -0,0 +1,200 @@ +//=========================================================================== +// +// File: MiscibilityLiveGas.cpp +// +// Created: Wed Feb 10 09:21:53 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + + +#include +#include "MiscibilityLiveGas.hpp" +#include +#include + +using namespace std; +using namespace Dune; + +namespace samcode +{ + + //------------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------------- + + /// Constructor + MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg) + { + // GAS, PVTG + const double bar = 1e5; + const double VISCOSITY_UNIT = 1e-3; + const int region_number = 0; + if (pvtg.size() != 1) { + THROW("More than one PVD-region"); + } + saturated_gas_table_.resize(4); + const int sz = pvtg[region_number].size(); + for (int k=0; k<4; ++k) { + saturated_gas_table_[k].resize(sz); + } + for (int i=0; i saturated_gas_table_[0][ltp]) { + return linearInterpolationExtrap(undersat_gas_tables_[ltp][0], + undersat_gas_tables_[ltp][item], + maxR); + } + + // Interpolate between table sections + double w = (press - saturated_gas_table_[0][is]) / + (saturated_gas_table_[0][is+1] - + saturated_gas_table_[0][is]); + if (undersat_gas_tables_[is][0].size() < 2) { + double val = saturated_gas_table_[item][is] + + w*(saturated_gas_table_[item][is+1] - + saturated_gas_table_[item][is]); + return val; + } + double val1 = + linearInterpolationExtrap(undersat_gas_tables_[is][0], + undersat_gas_tables_[is][item], + maxR); + double val2 = + linearInterpolationExtrap(undersat_gas_tables_[is+1][0], + undersat_gas_tables_[is+1][item], + maxR); + double val = val1 + w*(val2 - val1); + return val; + } + } + } + + +} // namespace samcode diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp new file mode 100644 index 00000000..e79329a4 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp @@ -0,0 +1,51 @@ +//=========================================================================== +// +// File: MiscibilityLiveGas.hpp +// +// Created: Wed Feb 10 09:21:26 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#ifndef SINTEF_MISCIBILITYLIVEGAS_HEADER +#define SINTEF_MISCIBILITYLIVEGAS_HEADER + + /** Class for miscible wet gas. + * Detailed description. + */ + +#include "MiscibilityProps.hpp" + +namespace samcode +{ + class MiscibilityLiveGas : public MiscibilityProps + { + public: + typedef std::vector > > table_t; + + MiscibilityLiveGas(const table_t& pvto); + virtual ~MiscibilityLiveGas(); + + virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; + virtual double R(int region, double press, const surfvol_t& surfvol) const; + virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; + virtual double B(int region, double press, const surfvol_t& surfvol) const; + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; + + protected: + // item: 1=B 2=mu; + double miscible_gas(double press, const surfvol_t& surfvol, int item, + bool deriv = false) const; + // PVT properties of wet gas (with vaporised oil) + std::vector > saturated_gas_table_; + std::vector > > undersat_gas_tables_; + + }; + +} + +#endif // SINTEF_MISCIBILITYLIVEGAS_HEADER + diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp new file mode 100644 index 00000000..4ba68593 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -0,0 +1,203 @@ +//=========================================================================== +// +// File: MiscibiltyLiveOil.cpp +// +// Created: Wed Feb 10 09:08:25 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#include +#include "MiscibilityLiveOil.hpp" +#include +#include + +using namespace std; +using namespace Dune; + +namespace samcode +{ + + + //------------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------------- + + /// Constructor + MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto) + { + // OIL, PVTO + const double bar = 1e5; + const double VISCOSITY_UNIT = 1e-3; + const int region_number = 0; + if (pvto.size() != 1) { + THROW("More than one PVD-region"); + } + saturated_oil_table_.resize(4); + const int sz = pvto[region_number].size(); + for (int k=0; k<4; ++k) { + saturated_oil_table_[k].resize(sz); + } + for (int i=0; i saturated_oil_table_[0][ltp]) { + return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], + undersat_oil_tables_[ltp][item], + maxR); + } + + // Interpolate between table sections + double w = (maxR - saturated_oil_table_[3][is]) / + (saturated_oil_table_[3][is+1] - + saturated_oil_table_[3][is]); + if (undersat_oil_tables_[is][0].size() < 2) { + double val = saturated_oil_table_[item][is] + + w*(saturated_oil_table_[item][is+1] - + saturated_oil_table_[item][is]); + return val; + } + double val1 = + linearInterpolationExtrap(undersat_oil_tables_[is][0], + undersat_oil_tables_[is][item], + press); + double val2 = + linearInterpolationExtrap(undersat_oil_tables_[is+1][0], + undersat_oil_tables_[is+1][item], + press); + double val = val1 + w*(val2 - val1); + return val; + } + } + } + +} // namespace samcode diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp new file mode 100644 index 00000000..547a19a5 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -0,0 +1,51 @@ +//=========================================================================== +// +// File: MiscibilityLiveOil.hpp +// +// Created: Wed Feb 10 09:08:09 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#ifndef SINTEF_MISCIBILITYLIVEOIL_HEADER +#define SINTEF_MISCIBILITYLIVEOIL_HEADER + + /** Class for miscible live oil. + * Detailed description. + */ + +#include "MiscibilityProps.hpp" + +namespace samcode +{ + class MiscibilityLiveOil : public MiscibilityProps + { + public: + typedef std::vector > > table_t; + + MiscibilityLiveOil(const table_t& pvto); + virtual ~MiscibilityLiveOil(); + + virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; + virtual double R (int region, double press, const surfvol_t& surfvol) const; + virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; + virtual double B (int region, double press, const surfvol_t& surfvol) const; + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; + + protected: + // item: 1=B 2=mu; + double miscible_oil(double press, const surfvol_t& surfvol, int item, + bool deriv = false) const; + + // PVT properties of live oil (with dissolved gas) + std::vector > saturated_oil_table_; + std::vector > > undersat_oil_tables_; + }; + +} + +#endif // SINTEF_MISCIBILITYLIVEOIL_HEADER + diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp new file mode 100644 index 00000000..edb0e122 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp @@ -0,0 +1,34 @@ +//=========================================================================== +// +// File: MiscibilityProps.cpp +// +// Created: Wed Feb 10 09:05:05 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#include "MiscibilityProps.hpp" + +using namespace std; + +namespace samcode +{ + + + //------------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------------- + + /// Constructor + MiscibilityProps::MiscibilityProps() + { + } + + MiscibilityProps::~MiscibilityProps() + { + } + +} // namespace samcode diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp new file mode 100644 index 00000000..32cd0f58 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -0,0 +1,46 @@ +//=========================================================================== +// +// File: MiscibilityProps.hpp +// +// Created: Wed Feb 10 09:04:35 2010 +// +// Author: Bjørn Spjelkavik +// +// Revision: $Id$ +// +//=========================================================================== + +#ifndef SINTEF_MISCIBILITYPROPS_HEADER +#define SINTEF_MISCIBILITYPROPS_HEADER + + /** Base class for properties of fluids and rocks. + * Detailed description. + */ + +#include +#include + +namespace samcode +{ + + + class MiscibilityProps + { + public: + typedef std::tr1::array surfvol_t; + enum PhaseNames { Aqua = 0, Liquid = 1, Vapour = 2 }; + + MiscibilityProps(); + virtual ~MiscibilityProps(); + + virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const = 0; + virtual double B (int region, double press, const surfvol_t& surfvol) const = 0; + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const = 0; + virtual double R (int region, double press, const surfvol_t& surfvol) const = 0; + virtual double dRdp(int region, double press, const surfvol_t& surfvol) const = 0; + }; + +} // namespace samcode + +#endif // SINTEF_MISCIBILITYPROPS_HEADER + diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp new file mode 100644 index 00000000..f777c854 --- /dev/null +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -0,0 +1,81 @@ +//=========================================================================== +// +// File: MiscibilityWater.hpp +// +// Created: Tue May 18 10:26:13 2010 +// +// Author(s): Atgeirr F Rasmussen +// Bjørn Spjelkavik +// +// $Date$ +// +// $Revision$ +// +//=========================================================================== + +#ifndef OPENRS_MISCIBILITYWATER_HEADER +#define OPENRS_MISCIBILITYWATER_HEADER + +#include "MiscibilityProps.hpp" +#include + +// Forward declaration. +class PVTW; + +namespace samcode +{ + class MiscibilityWater : public MiscibilityProps + { + public: + typedef std::vector > table_t; + MiscibilityWater(const table_t& pvtw) + { + const int region_number = 0; + if (pvtw.size() != 1) { + THROW("More than one PVD-region"); + } + double b = pvtw[region_number][1]; + double comp = pvtw[region_number][2]; + double visc = pvtw[region_number][3]; + const double VISCOSITY_UNIT = 1e-3; + if (b == 1.0 && comp == 0) { + viscosity_ = visc*VISCOSITY_UNIT; + } else { + THROW("Compressible water not implemented."); + } + } + MiscibilityWater(double visc) + : viscosity_(visc) + { + } + virtual ~MiscibilityWater() + { + } + + virtual double getViscosity(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + { + return viscosity_; + } + virtual double B(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + { + return 1.0; + } + virtual double dBdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + { + return 0.0; + } + virtual double R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + { + return 0.0; + } + virtual double dRdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + { + return 0.0; + } + private: + double viscosity_; + }; + +} + +#endif // OPENRS_MISCIBILITYWATER_HEADER From f942d63bd4cd769e93c81e3b8eda6402debbdb93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:20:46 +0100 Subject: [PATCH 007/113] Moved remaining fluid files to subdirectory. --- .../fluid/FluidMatrixInteractionBlackoil.hpp | 218 ++++++++ .../blackoil/fluid/FluidSystemBlackoil.hpp | 503 ++++++++++++++++++ 2 files changed, 721 insertions(+) create mode 100644 dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp create mode 100644 dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp new file mode 100644 index 00000000..f341dca6 --- /dev/null +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -0,0 +1,218 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED +#define OPM_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace Opm +{ + +// Forward declaration needed by associated parameters class. +template +class FluidMatrixInteractionBlackoil; + +template +class FluidMatrixInteractionBlackoilParams +{ +public: + typedef ScalarT Scalar; + void init(const Dune::EclipseGridParser& ep) + { + // Extract input data. + const Dune::SGOF::table_t& sgof_table = ep.getSGOF().sgof_; + const Dune::SWOF::table_t& swof_table = ep.getSWOF().swof_; + if (sgof_table.size() != 1 || swof_table.size() != 1) { + std::cerr << "We must have exactly one SWOF and one SGOF table (at the moment).\n"; + throw std::logic_error("Not implemented"); + } + const std::vector& sw = swof_table[0][0]; + const std::vector& krw = swof_table[0][1]; + const std::vector& krow = swof_table[0][2]; + const std::vector& pcow_raw = swof_table[0][3]; + const std::vector& sg = sgof_table[0][0]; + const std::vector& krg = sgof_table[0][1]; + const std::vector& krog = sgof_table[0][2]; + const std::vector& pcog_raw = sgof_table[0][3]; + + // Create tables for krw, krow, krg and krog. + int samples = 200; + buildUniformMonotoneTable(sw, krw, samples, krw_); + buildUniformMonotoneTable(sw, krow, samples, krow_); + buildUniformMonotoneTable(sg, krg, samples, krg_); + buildUniformMonotoneTable(sg, krog, samples, krog_); + for (int i = 0; i < int(krw.size()); ++i) { + if (krw[i] > 0.0) { + krocw_ = krow[i]; + break; + } + } + + // Create tables for pcow and pcog. + // We must convert the pressures depending on units. + double pressure_unit = 0.0; + switch (unitsInParser(ep)) { + case Metric: + pressure_unit = Dune::unit::barsa; + break; + case Field: + pressure_unit = Dune::unit::psia; + break; + case Lab: + case Pvtm: + pressure_unit = Dune::unit::atm; + break; + default: + throw std::logic_error("Unknown unit system."); + } + int numw = sw.size(); + std::vector pcow(numw); + for (int i = 0; i < numw; ++i) { + pcow[i] = Dune::unit::convert::from(pcow_raw[i], pressure_unit); + } + int numg = sg.size(); + std::vector pcog(numg); + for (int i = 0; i < numg; ++i) { + pcog[i] = Dune::unit::convert::from(pcog_raw[i], pressure_unit); + } + buildUniformMonotoneTable(sw, pcow, samples, pcow_); + buildUniformMonotoneTable(sg, pcog, samples, pcog_); + } + +private: + template + friend class FluidMatrixInteractionBlackoil; + + Dune::utils::UniformTableLinear krw_; + Dune::utils::UniformTableLinear krow_; + Dune::utils::UniformTableLinear pcow_; + Dune::utils::UniformTableLinear krg_; + Dune::utils::UniformTableLinear krog_; + Dune::utils::UniformTableLinear pcog_; + Scalar krocw_; // = krow_(s_wc) + + enum EclipseUnitFamily { Metric = 0, Field = 1, Lab = 2, Pvtm = 3 }; + EclipseUnitFamily unitsInParser(const Dune::EclipseGridParser& ep) + { + if (ep.hasField("FIELD")) return Field; + if (ep.hasField("LAB")) return Lab; + if (ep.hasField("PVT-M")) return Pvtm; + return Metric; // The default. + } +}; + + +/*! + * \ingroup material + * + * \brief Capillary pressures and relative permeabilities for a black oil system. + */ +template > +class FluidMatrixInteractionBlackoil +{ +public: + typedef ParamsT Params; + typedef typename Params::Scalar Scalar; + enum { numPhases = 3 }; + enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + + /*! + * \brief The linear capillary pressure-saturation curve. + * + * This material law is linear: + * \f[ + p_C = (1 - \overline{S}_w) (p_{C,max} - p_{C,entry}) + p_{C,entry} + \f] + * + * \param Swe Effective saturation of of the wetting phase \f$\overline{S}_w\f$ + */ + template + static void pC(pcContainerT &pc, + const Params ¶ms, + const SatContainerT &saturations, + Scalar /*temperature*/) + { + Scalar sw = saturations[Aqua]; + Scalar sg = saturations[Vapour]; + pc[Liquid] = 0.0; + pc[Aqua] = params.pcow_(sw); + pc[Vapour] = params.pcog_(sg); + } + + /*! + * \brief The saturation-capillary pressure curve. + * + * This is the inverse of the capillary pressure-saturation curve: + * \f[ + S_w = 1 - \frac{p_C - p_{C,entry}}{p_{C,max} - p_{C,entry}} + \f] + * + * \param pC Capillary pressure \f$\p_C\f$ + * \return The effective saturaion of the wetting phase \f$\overline{S}_w\f$ + */ + template + static void S(SatContainerT &saturations, + const Params ¶ms, + const pcContainerT &pc, + Scalar /*temperature*/) + { + std::cerr << "FluidMatrixInteractionBlackoil::S() is not implemented yet\n"; + throw std::logic_error("Not implemented"); + } + + + /*! + * \brief The relative permeability of all phases. + */ + template + static void kr(krContainerT &kr, + const Params ¶ms, + const SatContainerT &saturations, + Scalar /*temperature*/) + { + // Stone-II relative permeability model. + Scalar sw = saturations[Aqua]; + Scalar sg = saturations[Vapour]; + Scalar so = saturations[Liquid]; + Scalar krw = params.krw_(sw); + Scalar krg = params.krg_(sg); + Scalar krow = params.krow_(so); + Scalar krog = params.krog_(sg); + Scalar krocw = params.krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + } +}; + +} // namespace Opm + + + + +#endif // OPM_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp new file mode 100644 index 00000000..b01114b2 --- /dev/null +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -0,0 +1,503 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED +#define OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED + +#include +#include + +namespace Opm +{ + +// Forward declaration needed by associated parameters classes. +template +class FluidMatrixInteractionBlackoil; + + +class FluidSystemBlackoilParametersNonmiscible +{ +public: + void init(const Dune::EclipseGridParser& ep) + { + const std::vector >& pvtw_table = ep.getPVTW().pvtw_; + const Dune::PVDG::table_t& pvdg_table = ep.getPVDG().pvdg_; + const Dune::PVDO::table_t& pvdo_table = ep.getPVDO().pvdo_; + if (pvtw_table.size() != 1 || pvdg_table.size() != 1 || pvdo_table.size() != 1) { + std::cerr << "We must have exactly one PVT table per phase (at the moment).\n"; + throw std::logic_error("Not implemented"); + } + } +private: +}; + + +/*! + * \brief A black oil fluid system. + */ +template +class FluidSystemBlackoil +{ +public: + typedef ParamsT Params; + typedef double Scalar; + + enum { numComponents = 3 }; + enum { numPhases = 3 }; + + enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; + enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + + + /*! + * \brief Initialize system from input. + */ + static void init(const Dune::EclipseGridParser& ep) + { + params().init(ep); + } + + /*! + * \brief Return a human-readable phase name. + */ + static const char* phaseName(int phaseIdx) + { + switch (phaseIdx) { + case Aqua: return "aqua"; + case Vapour: return "vapour"; + case Liquid: return "liquid"; + default: throw std::logic_error("No such phase."); + } + } + + /*! + * \brief Return a human-readable component name. + */ + static const char* componentName(int compIdx) + { + switch (compIdx) { + case Water: return "water"; + case Gas: return "gas"; + case Oil: return "oil"; + default: throw std::logic_error("No such component."); + } + } + + +#if 0 + /*! + * \brief Return the molar mass of a component [kg/mol]. + */ + static Scalar molarMass(int compIdx) + { + + } + + /*! + * \brief Given a phase's composition, temperature, pressure, and + * the partial pressures of all components, return its + * density [kg/m^3]. + */ + template + static Scalar phaseDensity(int phaseIdx, + Scalar temperature, + Scalar pressure, + const FluidState &fluidState) + { + if (phaseIdx == lPhaseIdx) { + // See: Ochs 2008 + // \todo: proper citation + Scalar rholH2O = H2O::liquidDensity(temperature, pressure); + Scalar clH2O = rholH2O/H2O::molarMass(); + + // this assumes each nitrogen molecule displaces exactly one + // water molecule in the liquid + return + clH2O*(H2O::molarMass()*fluidState.moleFrac(lPhaseIdx, H2OIdx) + + + N2::molarMass()*fluidState.moleFrac(lPhaseIdx, N2Idx)); + } + else if (phaseIdx == gPhaseIdx) { + Scalar fugH2O = + fluidState.moleFrac(gPhaseIdx, H2OIdx) * + fluidState.phasePressure(gPhaseIdx); + Scalar fugN2 = + fluidState.moleFrac(gPhaseIdx, N2Idx) * + fluidState.phasePressure(gPhaseIdx); + return + H2O::gasDensity(temperature, fugH2O) + + N2::gasDensity(temperature, fugN2); + } + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + } + + /*! + * \brief Given a phase's composition, temperature and pressure, + * return its viscosity. + */ + template + static Scalar phaseViscosity(int phaseIdx, + Scalar temperature, + Scalar pressure, + const FluidState &fluidState) + { + if (phaseIdx == lPhaseIdx) { + // assume pure water for the liquid phase + // TODO: viscosity of mixture + return H2O::liquidViscosity(temperature, + pressure); + } + else { + return N2::gasViscosity(temperature, + pressure); + /* Wilke method. See: + * + * S.O.Ochs: "Development of a multiphase multicomponent + * model for PEMFC - Technical report: IRTG-NUPUS", + * University of Stuttgart, 2008 + * + * and: + * + * See: R. Reid, et al.: The Properties of Gases and Liquids, 4th + * edition, McGraw-Hill, 1987, 407-410 + */ + Scalar muResult = 0; + const Scalar mu[numComponents] = { + H2O::gasViscosity(temperature, + H2O::vaporPressure(temperature)), + N2::gasViscosity(temperature, + pressure) + }; + // molar masses + const Scalar M[numComponents] = { + H2O::molarMass(), + N2::molarMass() + }; + + for (int i = 0; i < numComponents; ++i) { + Scalar divisor = 0; + for (int j = 0; j < numComponents; ++j) { + Scalar phiIJ = 1 + sqrt(mu[i]/mu[j] * + pow(M[i]/M[j], 1/4.0)); + phiIJ *= phiIJ; + phiIJ /= sqrt(8*(1 + M[i]/M[j])); + divisor += fluidState.moleFrac(phaseIdx, j)*phiIJ; + } + muResult += fluidState.moleFrac(phaseIdx, i)*mu[i] / divisor; + } + + return muResult; + } + } + + + /*! + * \brief Assuming the composition of a single phase and the + * pressure of all phases is known or that all phases are + * present, compute the thermodynamic equilibrium from the + * temperature and phase pressures. If the known phase + * index + * + */ + template + static void computeEquilibrium(FluidState &fluidState, + int knownPhaseIdx = -1) + { + const Scalar T = fluidState.temperature(); + const Scalar pg = fluidState.phasePressure(gPhaseIdx); + const Scalar pl = fluidState.phasePressure(lPhaseIdx); + + const Scalar betaH2O = H2O::vaporPressure(T); + const Scalar betaN2 = BinaryCoeff::H2O_N2::henry(T); + + if (knownPhaseIdx < 0) + { + // we only have all phase pressures and temperature and + // know that all phases are present + Scalar xlH2O = (pg - betaN2)/(betaH2O - betaN2); + Scalar xlN2 = 1 - xlH2O; + Scalar rhol = liquidPhaseDensity_(T, pl, xlH2O, xlN2); + + Scalar cgH2O = H2O::gasDensity(T, betaH2O*xlH2O)/H2O::molarMass(); + Scalar cgN2 = N2::gasDensity(T, betaN2*xlN2)/N2::molarMass(); + + Scalar xgH2O = cgH2O/(cgH2O + cgN2); + Scalar xgN2 = cgN2/(cgH2O + cgN2); + + // set the liquid phase composition + SettablePhase liquid; + liquid.moleFrac_[H2OIdx] = xlH2O; + liquid.moleFrac_[N2Idx] = xlN2; + liquid.pressure_ = pl; + liquid.density_ = rhol; + liquid.xToX(); // compute mass fractions from mole fractions + fluidState.assignPhase(lPhaseIdx, liquid); + + // set the gas phase composition + SettablePhase gas; + gas.moleFrac_[H2OIdx] = xgH2O; + gas.moleFrac_[N2Idx] = xgN2; + gas.pressure_ = pg; + gas.density_ = cgH2O*H2O::molarMass() + cgN2*N2::molarMass(); + gas.xToX(); // compute mass fractions from mole fractions + fluidState.assignPhase(gPhaseIdx, gas); + } + else if (knownPhaseIdx == lPhaseIdx) { + // the composition of the liquid phase is given + + // retrieve the known mole fractions from the fluid state + Scalar xlH2O = fluidState.moleFrac(lPhaseIdx, H2OIdx); + Scalar xlN2 = fluidState.moleFrac(lPhaseIdx, N2Idx); + + // calculate the component contentrations in the gas phase + Scalar pH2O = betaH2O*xlH2O; // fugacity of water + Scalar pN2 = betaN2*xlN2; // fugacity of nitrogen + Scalar cgH2O = H2O::gasDensity(T, pH2O)/H2O::molarMass(); + Scalar cgN2 = N2::gasDensity(T, pN2)/N2::molarMass(); + + // convert concentrations to mole fractions + Scalar xgH2O = cgH2O/(cgH2O + cgN2) * (pH2O + pN2)/pg; + Scalar xgN2 = cgN2/(cgH2O + cgN2) * (pH2O + pN2)/pg; + + // set gas phase composition + SettablePhase gas; + gas.moleFrac_[H2OIdx] = xgH2O; + gas.moleFrac_[N2Idx] = xgN2; + gas.pressure_ = pg; + gas.density_ = cgH2O*H2O::molarMass() + cgN2*N2::molarMass(); + gas.xToX(); // update mass fractions from mole fractions + fluidState.assignPhase(gPhaseIdx, gas); + } + else if (knownPhaseIdx == gPhaseIdx) { + // the composition of the gas phase is given + + Scalar xgH2O = fluidState.moleFrac(gPhaseIdx, H2OIdx); + Scalar xgN2 = fluidState.moleFrac(gPhaseIdx, N2Idx); + Scalar pgH2O = pg*xgH2O; + Scalar pgN2 = pg*xgN2; + + Scalar xlH2O = pgH2O/betaH2O; + Scalar xlN2 = pgN2/betaN2; + + SettablePhase liquid; + liquid.moleFrac_[H2OIdx] = xlH2O; + liquid.moleFrac_[N2Idx] = xlN2; + liquid.pressure_ = pl; + liquid.density_ = liquidPhaseDensity_(T, pl, xlH2O, xlN2); + liquid.xToX(); // update mass fractions from mole fractions + fluidState.assignPhase(lPhaseIdx, liquid); + } + } + + /*! + * \brief Returns the activity coefficient of a component in a + * phase. + * + * We define the activity coefficent \f$\gamma_{\alpha,\kappa}\f$ + * of component \f$\kappa\f$ by the following equation: + * \f[ f_\kappa = p_\alpha \gamma_{\alpha,\kappa} \f] + * where \f$f_\kappa\f$ is the component's fugacity and \f$p_\alpha\f$ + * is the phase' pressure + * + * For liquids with very low miscibility this boils down to the + * inverse Henry constant for the solutes and the partial pressure + * for the solvent. + * + * For ideal gases this is equivalent to the gas pressure, in real + * gases it is the gas pressure times the component's fugacity + * coefficient. + */ + template + static Scalar activityCoeff(int phaseIdx, + int compIdx, + Scalar temperature, + Scalar pressure, + const FluidState &state) + { + if (phaseIdx == gPhaseIdx) { + return pressure; + Scalar fugH2O = std::max(1e-3, state.fugacity(H2OIdx)); + Scalar fugN2 = std::max(1e-3, state.fugacity(N2Idx)); + Scalar cH2O = H2O::gasDensity(temperature, fugH2O) / H2O::molarMass(); + Scalar cN2 = N2::gasDensity(temperature, fugN2) / N2::molarMass(); + + Scalar alpha = (fugH2O + fugN2)/pressure; + + if (compIdx == H2OIdx) + return fugH2O/(alpha*cH2O/(cH2O + cN2)); + else if (compIdx == N2Idx) + return fugN2/(alpha*cN2/(cH2O + cN2)); + + DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + + switch (compIdx) { + case H2OIdx: return H2O::vaporPressure(temperature); + case N2Idx: return BinaryCoeff::H2O_N2::henry(temperature); + }; + DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + } + + /*! + * \brief Given a phase's composition, temperature and pressure, + * return the binary diffusion coefficent for components + * \f$i\f$ and \f$j\f$ in this phase. + */ + template + static Scalar diffCoeff(int phaseIdx, + int compIIdx, + int compJIdx, + Scalar temperature, + Scalar pressure, + const FluidState &fluidState) + { + if (compIIdx > compJIdx) + std::swap(compIIdx, compJIdx); + +#ifndef NDEBUG + if (compIIdx == compJIdx || + phaseIdx > numPhases - 1 || + compJIdx > numComponents - 1) + { + DUNE_THROW(Dune::InvalidStateException, + "Binary diffusion coefficient of components " + << compIIdx << " and " << compJIdx + << " in phase " << phaseIdx << " is undefined!\n"); + } +#endif + + + switch (phaseIdx) { + case lPhaseIdx: + switch (compIIdx) { + case H2OIdx: + switch (compJIdx) { + case N2Idx: return BinaryCoeff::H2O_N2::liquidDiffCoeff(temperature, + pressure); + } + default: + DUNE_THROW(Dune::InvalidStateException, + "Binary diffusion coefficients of trace " + "substances in liquid phase is undefined!\n"); + } + case gPhaseIdx: + switch (compIIdx) { + case H2OIdx: + switch (compJIdx) { + case N2Idx: return BinaryCoeff::H2O_N2::gasDiffCoeff(temperature, + pressure); + } + } + } + + DUNE_THROW(Dune::InvalidStateException, + "Binary diffusion coefficient of components " + << compIIdx << " and " << compJIdx + << " in phase " << phaseIdx << " is undefined!\n"); + }; + + /*! + * \brief Given a phase's composition, temperature and pressure, + * return its specific enthalpy [J/kg]. + */ + template + static Scalar phaseEnthalpy(int phaseIdx, + Scalar temperature, + Scalar pressure, + const FluidState &fluidState) + { + if (phaseIdx == lPhaseIdx) { + Scalar cN2 = fluidState.concentration(lPhaseIdx, N2Idx); + Scalar pN2 = N2::gasPressure(temperature, cN2*N2::molarMass()); + + // TODO: correct way to deal with the solutes??? + return + fluidState.massFrac(lPhaseIdx, H2OIdx)* + H2O::liquidEnthalpy(temperature, pressure) + + + fluidState.massFrac(lPhaseIdx, N2Idx)* + N2::gasEnthalpy(temperature, pN2); + } + else { + Scalar cH2O = fluidState.concentration(gPhaseIdx, H2OIdx); + Scalar cN2 = fluidState.concentration(gPhaseIdx, N2Idx); + + Scalar pH2O = H2O::gasPressure(temperature, cH2O*H2O::molarMass()); + Scalar pN2 = N2::gasPressure(temperature, cN2*N2::molarMass()); + + Scalar result = 0; + result += + H2O::gasEnthalpy(temperature, pH2O) * + fluidState.massFrac(gPhaseIdx, H2OIdx); + result += + N2::gasEnthalpy(temperature, pN2) * + fluidState.massFrac(gPhaseIdx, N2Idx); + + return result; + } + } + + /*! + * \brief Given a phase's composition, temperature and pressure, + * return its specific internal energy [J/kg]. + */ + template + static Scalar phaseInternalEnergy(int phaseIdx, + Scalar temperature, + Scalar pressure, + const FluidState &fluidState) + { + return + phaseEnthalpy(phaseIdx, temperature, pressure, fluidState) - + pressure/phaseDensity(phaseIdx, temperature, pressure, fluidState); + } + +private: + static Scalar liquidPhaseDensity_(Scalar T, Scalar pl, Scalar xlH2O, Scalar xlN2) + { + // See: Ochs 2008 + // \todo: proper citation + Scalar rholH2O = H2O::liquidDensity(T, pl); + Scalar clH2O = rholH2O/H2O::molarMass(); + + // this assumes each nitrogen molecule displaces exactly one + // water molecule in the liquid + return + clH2O*(xlH2O*H2O::molarMass() + + + xlN2*N2::molarMass()); + } + + static Scalar gasPhaseDensity_(Scalar T, Scalar pg, Scalar xgH2O, Scalar xgN2) + { + return H2O::gasDensity(T, pg*xgH2O) + N2::gasDensity(T, pg*xgN2); + }; + +#endif + + static Params& params() + { + static Params params; + return params; + } +}; + +} // namespace Opm + +#endif // OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED From bc1c40a03a0d5780d60cca1c3c9eda3764a64f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:21:46 +0100 Subject: [PATCH 008/113] Fixed to account for move in last commit. --- dune/porsol/blackoil/test/bo_fluid_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/dune/porsol/blackoil/test/bo_fluid_test.cpp index ed848d9c..75af0ad5 100644 --- a/dune/porsol/blackoil/test/bo_fluid_test.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_test.cpp @@ -18,8 +18,8 @@ */ -#include -#include +#include +#include #include #include From 00673d9367f6b5f86fd2f5ea887a6c567c3498d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:28:55 +0100 Subject: [PATCH 009/113] Changed namespace to Opm. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 105 ++++++++++++++++++ dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 18 +-- .../fluid/FluidMiscibilityThreePhase.cpp | 4 +- .../fluid/FluidMiscibilityThreePhase.hpp | 2 +- .../porsol/blackoil/fluid/MiscibilityDead.cpp | 2 +- .../porsol/blackoil/fluid/MiscibilityDead.hpp | 2 +- .../blackoil/fluid/MiscibilityLiveGas.cpp | 4 +- .../blackoil/fluid/MiscibilityLiveGas.hpp | 2 +- .../blackoil/fluid/MiscibilityLiveOil.cpp | 4 +- .../blackoil/fluid/MiscibilityLiveOil.hpp | 2 +- .../blackoil/fluid/MiscibilityProps.cpp | 4 +- .../blackoil/fluid/MiscibilityProps.hpp | 4 +- .../blackoil/fluid/MiscibilityWater.hpp | 2 +- 13 files changed, 131 insertions(+), 24 deletions(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index aa42e90e..907b9a67 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -17,3 +17,108 @@ along with OPM. If not, see . */ + +#include "BlackoilPVT.hpp" +#include +#include "MiscibilityDead.hpp" +#include "MiscibilityLiveOil.hpp" +#include "MiscibilityLiveGas.hpp" +#include "MiscibilityWater.hpp" +#include +#include + +using namespace Dune; + +namespace Opm +{ + + + void BlackoilPVT::init(const Dune::EclipseGridParser& parser) + { + typedef std::vector > > table_t; + region_number_ = 0; + + // Surface densities. Accounting for different orders in eclipse and our code. + if (parser.hasField("DENSITY")) { + const int region_number = 0; + enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; + const std::vector > d_tmp = + parser.getDENSITY().densities_; + densities_[Aqua] = d_tmp[region_number][ECL_water]; + densities_[Liquid] = d_tmp[region_number][ECL_oil]; + densities_[Vapour] = d_tmp[region_number][ECL_gas]; + } else { + THROW("Input is missing DENSITY\n"); + } + + // Water PVT + if (parser.hasField("PVTW")) { + water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_)); + } else { + water_props_.reset(new MiscibilityWater(3e-4)); // Default is 0.3 cP. + } + + // Oil PVT + if (parser.hasField("PVDO")) { + oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_)); + } else if (parser.hasField("PVTO")) { + oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_)); + } else { + THROW("Input is missing PVDO and PVTO\n"); + } + + // Gas PVT + if (parser.hasField("PVDG")) { + gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_)); + } else if (parser.hasField("PVTG")) { + gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_)); + } else { + THROW("Input is missing PVDG and PVTG\n"); + } + } + + BlackoilPVT::surfvol_t BlackoilPVT::surfaceDensities() const + { + return densities_; + } + + double BlackoilPVT::getViscosity(double press, const surfvol_t& surfvol, PhaseIndex phase) const + { + return propsForPhase(phase).getViscosity(region_number_, press, surfvol); + } + + double BlackoilPVT::B(double press, const surfvol_t& surfvol, PhaseIndex phase) const + { + return propsForPhase(phase).B(region_number_, press, surfvol); + } + + double BlackoilPVT::dBdp(double press, const surfvol_t& surfvol, PhaseIndex phase) const + { + return propsForPhase(phase).dBdp(region_number_, press, surfvol); + } + + double BlackoilPVT::R(double press, const surfvol_t& surfvol, PhaseIndex phase) const + { + return propsForPhase(phase).R(region_number_, press, surfvol); + } + + double BlackoilPVT::dRdp(double press, const surfvol_t& surfvol, PhaseIndex phase) const + { + return propsForPhase(phase).dRdp(region_number_, press, surfvol); + } + + const MiscibilityProps& BlackoilPVT::propsForPhase(PhaseIndex phase) const + { + switch (phase) { + case Aqua: + return *water_props_; + case Liquid: + return *oil_props_; + case Vapour: + return *gas_props_; + default: + THROW("Unknown phase accessed: " << phase); + } + } + +} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp index 698daa0f..80414085 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -21,9 +21,11 @@ #define OPM_BLACKOILPVT_HEADER_INCLUDED -#include -#include #include "MiscibilityProps.hpp" +#include +#include +#include + namespace Opm { @@ -37,22 +39,22 @@ namespace Opm void init(const Dune::EclipseGridParser& ep); double getViscosity(double press, const surfvol_t& surfvol, - PhaseNames phase) const; + PhaseIndex phase) const; surfvol_t getMobilities(double press, const surfvol_t& sat, const surfvol_t& surfvol) const; surfvol_t surfaceDensities() const; double B (double press, const surfvol_t& surfvol, - PhaseNames phase) const; + PhaseIndex phase) const; double dBdp(double press, const surfvol_t& surfvol, - PhaseNames phase) const; + PhaseIndex phase) const; double R (double press, const surfvol_t& surfvol, - PhaseNames phase) const; + PhaseIndex phase) const; double dRdp(double press, const surfvol_t& surfvol, - PhaseNames phase) const; + PhaseIndex phase) const; private: int region_number_; - const MiscibilityProps& propsForPhase(PhaseNames phase) const; + const MiscibilityProps& propsForPhase(PhaseIndex phase) const; boost::scoped_ptr water_props_; boost::scoped_ptr oil_props_; diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp index a25f0dce..6ae741d7 100644 --- a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp +++ b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp @@ -21,7 +21,7 @@ using namespace Dune; -namespace samcode +namespace Opm { @@ -239,4 +239,4 @@ namespace samcode } -} // namespace samcode +} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp index 0b0243a0..369b413b 100644 --- a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp +++ b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp @@ -20,7 +20,7 @@ #include #include "MiscibilityProps.hpp" -namespace samcode +namespace Opm { class FluidMiscibilityThreePhase { diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index fca1a1b3..091dd93f 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -18,7 +18,7 @@ using namespace std; using namespace Dune; -namespace samcode +namespace Opm { //------------------------------------------------------------------------ diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp index a27cf801..8e7146aa 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp @@ -19,7 +19,7 @@ #include "MiscibilityProps.hpp" -namespace samcode +namespace Opm { class MiscibilityDead : public MiscibilityProps { diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp index b784523a..74ce0c9b 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -19,7 +19,7 @@ using namespace std; using namespace Dune; -namespace samcode +namespace Opm { //------------------------------------------------------------------------ @@ -197,4 +197,4 @@ namespace samcode } -} // namespace samcode +} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp index e79329a4..20f1ed03 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp @@ -19,7 +19,7 @@ #include "MiscibilityProps.hpp" -namespace samcode +namespace Opm { class MiscibilityLiveGas : public MiscibilityProps { diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 4ba68593..ece1b555 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -18,7 +18,7 @@ using namespace std; using namespace Dune; -namespace samcode +namespace Opm { @@ -200,4 +200,4 @@ namespace samcode } } -} // namespace samcode +} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp index 547a19a5..cb6eca4e 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -19,7 +19,7 @@ #include "MiscibilityProps.hpp" -namespace samcode +namespace Opm { class MiscibilityLiveOil : public MiscibilityProps { diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp index edb0e122..202ed689 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp @@ -14,7 +14,7 @@ using namespace std; -namespace samcode +namespace Opm { @@ -31,4 +31,4 @@ namespace samcode { } -} // namespace samcode +} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp index 32cd0f58..ae31610a 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -20,7 +20,7 @@ #include #include -namespace samcode +namespace Opm { @@ -40,7 +40,7 @@ namespace samcode virtual double dRdp(int region, double press, const surfvol_t& surfvol) const = 0; }; -} // namespace samcode +} // namespace Opm #endif // SINTEF_MISCIBILITYPROPS_HEADER diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index f777c854..2d743a38 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -22,7 +22,7 @@ // Forward declaration. class PVTW; -namespace samcode +namespace Opm { class MiscibilityWater : public MiscibilityProps { From 6893452661d835115dbe6aad9288cced9f0a3870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:29:46 +0100 Subject: [PATCH 010/113] Removed, PVT functionality now in BlackOilPVT. --- .../fluid/FluidMiscibilityThreePhase.cpp | 242 ------------------ .../fluid/FluidMiscibilityThreePhase.hpp | 78 ------ 2 files changed, 320 deletions(-) delete mode 100644 dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp delete mode 100644 dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp deleted file mode 100644 index 6ae741d7..00000000 --- a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.cpp +++ /dev/null @@ -1,242 +0,0 @@ -//=========================================================================== -// -// File: FluidMiscibilityThreePhase.cpp -// -// Created: Wed Feb 10 09:25:57 2010 -// -// Author: Bjørn Spjelkavik -// -// Revision: $Id$ -// -//=========================================================================== - -#include "FluidMiscibilityThreePhase.hpp" -#include -#include "MiscibilityDead.hpp" -#include "MiscibilityLiveOil.hpp" -#include "MiscibilityLiveGas.hpp" -#include "MiscibilityWater.hpp" -#include -#include - -using namespace Dune; - -namespace Opm -{ - - - void FluidMiscibilityThreePhase::init(const std::string& pvt_filename) - { - typedef std::vector > > table_t; - region_number_ = 0; - Dune::EclipseGridParser eclipse_props(pvt_filename); - - // Surface densities. Accounting for different orders in eclipse and our code. - if (eclipse_props.hasField("DENSITY")) { - const int region_number = 0; - enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; - const std::vector > d_tmp = - eclipse_props.getDENSITY().densities_; - densities_[Aqua] = d_tmp[region_number][ECL_water]; - densities_[Liquid] = d_tmp[region_number][ECL_oil]; - densities_[Vapour] = d_tmp[region_number][ECL_gas]; - } else { - THROW("DENSITY not defined"); - } - - // Water PVT - if (eclipse_props.hasField("PVTW")) { - water_props_.reset(new MiscibilityWater(eclipse_props.getPVTW().pvtw_)); - } else { - water_props_.reset(new MiscibilityWater(3e-4)); // Default is 0.3 cP. - } - - // Oil PVT - if (eclipse_props.hasField("PVDO")) { - oil_props_.reset(new MiscibilityDead(eclipse_props.getPVDO().pvdo_)); - } else if (eclipse_props.hasField("PVTO")) { - oil_props_.reset(new MiscibilityLiveOil(eclipse_props.getPVTO().pvto_)); - } else { - THROW("File " << pvt_filename << " is missing PVDO and PVTO\n"); - } - - // Gas PVT - if (eclipse_props.hasField("PVDG")) { - gas_props_.reset(new MiscibilityDead(eclipse_props.getPVDG().pvdg_)); - } else if (eclipse_props.hasField("PVTG")) { - gas_props_.reset(new MiscibilityLiveGas(eclipse_props.getPVTG().pvtg_)); - } else { - THROW("File " << pvt_filename << " is missing PVDG and PVTG\n"); - } - - //SWOF - if (eclipse_props.hasField("SWOF")) { - swof_ = eclipse_props.getSWOF().swof_; - } - - //SGOF - if (eclipse_props.hasField("SGOF")) { - sgof_ = eclipse_props.getSGOF().sgof_; - } - - } - FluidMiscibilityThreePhase::surfvol_t FluidMiscibilityThreePhase::surfaceDensities() const - { - return densities_; - } - - double FluidMiscibilityThreePhase::getViscosity(double press, const surfvol_t& surfvol, PhaseNames phase) const - { - return propsForPhase(phase).getViscosity(region_number_, press, surfvol); - } - - FluidMiscibilityThreePhase::surfvol_t - FluidMiscibilityThreePhase::getMobilities(double press, const surfvol_t& sat, - const surfvol_t& surfvol) const - { - if (swof_.empty() || sgof_.empty()) { - THROW("The SWOF and SGOF keywords were not given, cannot compute mobilities. Try tracer_flow=true."); - } - surfvol_t mobilities; - double sw = sat[Aqua]; - double sg = sat[Vapour]; - mobilities[Aqua] = krw(sw)/getViscosity(press, surfvol, Aqua); - mobilities[Liquid] = krow(sw)*krog(sg)/getViscosity(press, surfvol, Liquid); - mobilities[Vapour] = krg(sg)/getViscosity(press, surfvol, Vapour); - return mobilities; - } - - double FluidMiscibilityThreePhase::B(double press, const surfvol_t& surfvol, PhaseNames phase) const - { - return propsForPhase(phase).B(region_number_, press, surfvol); - } - - double FluidMiscibilityThreePhase::dBdp(double press, const surfvol_t& surfvol, PhaseNames phase) const - { - return propsForPhase(phase).dBdp(region_number_, press, surfvol); - } - - double FluidMiscibilityThreePhase::R(double press, const surfvol_t& surfvol, PhaseNames phase) const - { - return propsForPhase(phase).R(region_number_, press, surfvol); - } - - double FluidMiscibilityThreePhase::dRdp(double press, const surfvol_t& surfvol, PhaseNames phase) const - { - return propsForPhase(phase).dRdp(region_number_, press, surfvol); - } - - const MiscibilityProps& FluidMiscibilityThreePhase::propsForPhase(PhaseNames phase) const - { - switch (phase) { - case Aqua: - return *water_props_; - case Liquid: - return *oil_props_; - case Vapour: - return *gas_props_; - default: - THROW("Unknown phase accessed: " << phase); - } - } - - // Stone's first model(Modified) - double FluidMiscibilityThreePhase::kro(double sw, double sg) const - { - double so = 1.0-sw-sg; - double fw = krow(sw); - double fg = krog(sg); - return so*fw*fg; - } - - // kro partial derivative Sw - double FluidMiscibilityThreePhase::dkro_dsw(double sw, double sg) const - { - double so = 1.0-sw-sg; - double fw = krow(sw); - double fg = krog(sg); - double fwder = dkrow_dsw(sw); - return fg*(-fw + so*fwder); - } - - // kro partial derivative Sg - double FluidMiscibilityThreePhase::dkro_dsg(double sw, double sg) const - { - double so = 1.0-sw-sg; - double fw = krow(sw); - double fg = krog(sg); - double fgder = dkrog_dsg(sg); - return fw*(-fg + so*fgder); - } - - // kro partial derivatives - void FluidMiscibilityThreePhase::dkro(double sw, double sg, double& dkro_dsw, - double& dkro_dsg) const - { - double so = 1.0-sw-sg; - double fw = krow(sw); - double fg = krog(sg); - double fwder = dkrow_dsw(sw); - double fgder = dkrog_dsg(sg); - dkro_dsw = fg*(-fw + so*fwder); - dkro_dsg = fw*(-fg + so*fgder); - } - - // Water relative permeability - double FluidMiscibilityThreePhase::krw (double sw) const - { - return linearInterpolation(swof_[region_number_][0], - swof_[region_number_][1], sw); - } - - // Oil relative permeability - double FluidMiscibilityThreePhase::krow (double sw) const - { - return linearInterpolation(swof_[region_number_][0], - swof_[region_number_][2], sw); - } - - // krow derivative - double FluidMiscibilityThreePhase::dkrow_dsw(double sw) const - { - return linearInterpolDerivative(swof_[region_number_][0], - swof_[region_number_][2], sw); - } - - // Water-oil capillary pressure - double FluidMiscibilityThreePhase::Pcow (double sw) const - { - return linearInterpolation(swof_[region_number_][0], - swof_[region_number_][3], sw); - } - - // Gas relative permeability - double FluidMiscibilityThreePhase::krg (double sg) const - { - return linearInterpolation(sgof_[region_number_][0], - sgof_[region_number_][1], sg); - } - - // Oil relative permeability - double FluidMiscibilityThreePhase::krog (double sg) const - { - return linearInterpolation(sgof_[region_number_][0], - sgof_[region_number_][2], sg); - } - - // krog derivative - double FluidMiscibilityThreePhase::dkrog_dsg(double sg) const - { - return linearInterpolDerivative(sgof_[region_number_][0], - sgof_[region_number_][2], sg); - } - - // Oil-gas capillary pressure - double FluidMiscibilityThreePhase::Pcog(double sg) const - { - return linearInterpolation(sgof_[region_number_][0], - sgof_[region_number_][3], sg); - } - - -} // namespace Opm diff --git a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp b/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp deleted file mode 100644 index 369b413b..00000000 --- a/dune/porsol/blackoil/fluid/FluidMiscibilityThreePhase.hpp +++ /dev/null @@ -1,78 +0,0 @@ -//=========================================================================== -// -// File: FluidMiscibilityThreePhase.hpp -// -// Created: Thu Feb 11 10:35:05 2010 -// -// Author: Bjørn Spjelkavik -// -// Revision: $Id$ -// -//=========================================================================== - -#ifndef SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER -#define SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER - - /** Temporary class for testing Miscibility* classes - * Detailed description. - */ -#include -#include -#include "MiscibilityProps.hpp" - -namespace Opm -{ - class FluidMiscibilityThreePhase - { - public: - typedef MiscibilityProps::surfvol_t surfvol_t; - - enum PhaseNames { Aqua = 0, Liquid = 1, Vapour = 2 }; - - FluidMiscibilityThreePhase(){} - ~FluidMiscibilityThreePhase(){} - void init(const std::string& pvt_filename); - - double getViscosity(double press, const surfvol_t& surfvol, - PhaseNames phase) const; - surfvol_t getMobilities(double press, const surfvol_t& sat, const surfvol_t& surfvol) const; - surfvol_t surfaceDensities() const; - double B (double press, const surfvol_t& surfvol, - PhaseNames phase) const; - double dBdp(double press, const surfvol_t& surfvol, - PhaseNames phase) const; - double R (double press, const surfvol_t& surfvol, - PhaseNames phase) const; - double dRdp(double press, const surfvol_t& surfvol, - PhaseNames phase) const; - - - private: - int region_number_; - const MiscibilityProps& propsForPhase(PhaseNames phase) const; - double kro(double sw, double sg) const; // Stone's first model(Modified) - double dkro_dsw(double sw, double sg) const; // kro partial derivative dSw - double dkro_dsg(double sw, double sg) const; // kro partial derivative dSg - void dkro (double sw, double sg, // kro partial derivatives. dSw and dSg - double& dkro_dsw, double& dkro_dsg) const; - double krw (double sw) const; // Water relative permeability - double krow (double sw) const; // Oil relative permeability - double dkrow_dsw (double sw) const; // krow derivative - double Pcow (double sw) const; // Water-oil capillary pressure - double krg (double sg) const; // Gas relative permeability - double krog (double sg) const; // Oil relative permeability - double dkrog_dsg(double sg) const; // krog derivative - double Pcog (double sg) const; // Oil-gas capillary pressure - - boost::scoped_ptr water_props_; - boost::scoped_ptr oil_props_; - boost::scoped_ptr gas_props_; - surfvol_t densities_; - std::vector > > sgof_; // Gas/Oil saturation - std::vector > > swof_; // Water/Oil saturation - }; - -} - -#endif // SINTEF_FLUIDMISCIBILITYTHREEPHASE_HEADER - From 9a1f4180d24f2fd94ca9e33dc6ec5ce97147608a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Nov 2010 13:35:11 +0100 Subject: [PATCH 011/113] Now FluidSystemBlackoil uses the BlackoilPVT class for implementation. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index b01114b2..58d3331f 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -20,6 +20,7 @@ #ifndef OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED #define OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED +#include "BlackoilPVT.hpp" #include #include @@ -36,15 +37,10 @@ class FluidSystemBlackoilParametersNonmiscible public: void init(const Dune::EclipseGridParser& ep) { - const std::vector >& pvtw_table = ep.getPVTW().pvtw_; - const Dune::PVDG::table_t& pvdg_table = ep.getPVDG().pvdg_; - const Dune::PVDO::table_t& pvdo_table = ep.getPVDO().pvdo_; - if (pvtw_table.size() != 1 || pvdg_table.size() != 1 || pvdo_table.size() != 1) { - std::cerr << "We must have exactly one PVT table per phase (at the moment).\n"; - throw std::logic_error("Not implemented"); - } + pvt_.init(ep); } private: + BlackoilPVT pvt_; }; From d835d4fbb65cd753e81263c3398258e3b29e0303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 15 Nov 2010 07:57:36 +0100 Subject: [PATCH 012/113] Added proper copyright notice to files imported from samcode. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 6 ++++++ dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 1 - .../blackoil/fluid/FluidStateBlackoil.hpp | 4 ++++ dune/porsol/blackoil/fluid/MiscibilityDead.cpp | 18 ++++++++++++++++++ dune/porsol/blackoil/fluid/MiscibilityDead.hpp | 18 ++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveGas.cpp | 18 ++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveGas.hpp | 18 ++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveOil.cpp | 18 ++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveOil.hpp | 18 ++++++++++++++++++ .../porsol/blackoil/fluid/MiscibilityProps.cpp | 18 ++++++++++++++++++ .../porsol/blackoil/fluid/MiscibilityProps.hpp | 18 ++++++++++++++++++ .../porsol/blackoil/fluid/MiscibilityWater.hpp | 18 ++++++++++++++++++ 12 files changed, 172 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index 907b9a67..f7c32005 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -38,6 +38,12 @@ namespace Opm typedef std::vector > > table_t; region_number_ = 0; + + + + + + // Surface densities. Accounting for different orders in eclipse and our code. if (parser.hasField("DENSITY")) { const int region_number = 0; diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp index 80414085..dd97c590 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -40,7 +40,6 @@ namespace Opm double getViscosity(double press, const surfvol_t& surfvol, PhaseIndex phase) const; - surfvol_t getMobilities(double press, const surfvol_t& sat, const surfvol_t& surfvol) const; surfvol_t surfaceDensities() const; double B (double press, const surfvol_t& surfvol, PhaseIndex phase) const; diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 7197b7e8..5c36e69a 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -20,6 +20,10 @@ #ifndef OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED #define OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED + +#include "" + + namespace Opm { /*! diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 091dd93f..435fd034 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ #include #include "MiscibilityDead.hpp" diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp index 8e7146aa..9ff68688 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 SINTEF_MISCIBILITYDEAD_HEADER #define SINTEF_MISCIBILITYDEAD_HEADER diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp index 74ce0c9b..047af829 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ #include diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp index 20f1ed03..08dfc907 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 SINTEF_MISCIBILITYLIVEGAS_HEADER #define SINTEF_MISCIBILITYLIVEGAS_HEADER diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index ece1b555..ab5a0f58 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ #include #include "MiscibilityLiveOil.hpp" diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp index cb6eca4e..fb3abdd0 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 SINTEF_MISCIBILITYLIVEOIL_HEADER #define SINTEF_MISCIBILITYLIVEOIL_HEADER diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp index 202ed689..012606f7 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.cpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ #include "MiscibilityProps.hpp" diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp index ae31610a..7d0ba2c5 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -9,6 +9,24 @@ // Revision: $Id$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 SINTEF_MISCIBILITYPROPS_HEADER #define SINTEF_MISCIBILITYPROPS_HEADER diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index 2d743a38..e532e211 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -12,6 +12,24 @@ // $Revision$ // //=========================================================================== +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 OPENRS_MISCIBILITYWATER_HEADER #define OPENRS_MISCIBILITYWATER_HEADER From 532c6c5652d48daf2e3e1b15dc149a0b22004306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 15 Nov 2010 11:36:26 +0100 Subject: [PATCH 013/113] Work in progress on ensuring units are done correctly. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 21 +- .../blackoil/fluid/FluidStateBlackoil.hpp | 10 +- .../blackoil/fluid/FluidSystemBlackoil.hpp | 345 +++--------------- .../blackoil/fluid/MiscibilityWater.hpp | 26 +- 4 files changed, 87 insertions(+), 315 deletions(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index f7c32005..4df2ced7 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -38,30 +38,25 @@ namespace Opm typedef std::vector > > table_t; region_number_ = 0; - - - - - - // Surface densities. Accounting for different orders in eclipse and our code. if (parser.hasField("DENSITY")) { const int region_number = 0; enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; - const std::vector > d_tmp = - parser.getDENSITY().densities_; - densities_[Aqua] = d_tmp[region_number][ECL_water]; - densities_[Liquid] = d_tmp[region_number][ECL_oil]; - densities_[Vapour] = d_tmp[region_number][ECL_gas]; + const std::vector& d = parser.getDENSITY().densities_[region_number]; + const double du = parser.units().density; + using namespace Dune::unit; + densities_[Aqua] = convert::from(d[ECL_water], du); + densities_[Vapour] = convert::from(d[ECL_gas], du); + densities_[Liquid] = convert::from(d[ECL_oil], du); } else { THROW("Input is missing DENSITY\n"); } // Water PVT if (parser.hasField("PVTW")) { - water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_)); + water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_, parser.units())); } else { - water_props_.reset(new MiscibilityWater(3e-4)); // Default is 0.3 cP. + water_props_.reset(new MiscibilityWater(0.5*Dune::prefix::centi*Dune::unit::Poise)); // Eclipse 100 default } // Oil PVT diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 5c36e69a..bc7eb53d 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -233,13 +233,11 @@ public: { return temperature_; }; public: - Scalar fugacity_[numComponents]; - Scalar moleFrac_[numPhases][numComponents]; - Scalar phaseConcentration_[numPhases]; - Scalar meanMolarMass_[numPhases]; - Scalar phasePressure_[numPhases]; - Scalar saturation_[numPhases]; Scalar temperature_; + Scalar surface_volume_[numComponents]; + Scalar phase_pressure_[numPhases]; + Scalar phase_volume_[numPhases]; + Scalar saturation_[numPhases]; }; } // end namespace Opm diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 58d3331f..6077bc1c 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -1,3 +1,17 @@ +/***************************************************************************** + * Copyright (C) 2009 by Andreas Lauser + * Institute of Hydraulic Engineering * + * University of Stuttgart, Germany * + * email: .@iws.uni-stuttgart.de * + * * + * This program 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 2 of the License, or * + * (at your option) any later version, as long as this copyright notice * + * is included in its original form. * + * * + * This program is distributed WITHOUT ANY WARRANTY. * + *****************************************************************************/ /* Copyright 2010 SINTEF ICT, Applied Mathematics. @@ -28,11 +42,11 @@ namespace Opm { // Forward declaration needed by associated parameters classes. -template -class FluidMatrixInteractionBlackoil; +template +class FluidSystemBlackoil; - -class FluidSystemBlackoilParametersNonmiscible +// Parameters for the black oil fluid system. +class FluidSystemBlackoilParameters { public: void init(const Dune::EclipseGridParser& ep) @@ -40,6 +54,8 @@ public: pvt_.init(ep); } private: + template + friend class FluidSystemBlackoil; BlackoilPVT pvt_; }; @@ -47,7 +63,7 @@ private: /*! * \brief A black oil fluid system. */ -template +template class FluidSystemBlackoil { public: @@ -60,6 +76,7 @@ public: enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + typedef BlackoilPVT::surfvol_t FluidVec; /*! * \brief Initialize system from input. @@ -96,15 +113,15 @@ public: } -#if 0 /*! * \brief Return the molar mass of a component [kg/mol]. */ static Scalar molarMass(int compIdx) { - + throw std::logic_error("molarMass() not implemented."); } + /*! * \brief Given a phase's composition, temperature, pressure, and * the partial pressures of all components, return its @@ -116,31 +133,7 @@ public: Scalar pressure, const FluidState &fluidState) { - if (phaseIdx == lPhaseIdx) { - // See: Ochs 2008 - // \todo: proper citation - Scalar rholH2O = H2O::liquidDensity(temperature, pressure); - Scalar clH2O = rholH2O/H2O::molarMass(); - - // this assumes each nitrogen molecule displaces exactly one - // water molecule in the liquid - return - clH2O*(H2O::molarMass()*fluidState.moleFrac(lPhaseIdx, H2OIdx) - + - N2::molarMass()*fluidState.moleFrac(lPhaseIdx, N2Idx)); - } - else if (phaseIdx == gPhaseIdx) { - Scalar fugH2O = - fluidState.moleFrac(gPhaseIdx, H2OIdx) * - fluidState.phasePressure(gPhaseIdx); - Scalar fugN2 = - fluidState.moleFrac(gPhaseIdx, N2Idx) * - fluidState.phasePressure(gPhaseIdx); - return - H2O::gasDensity(temperature, fugH2O) + - N2::gasDensity(temperature, fugN2); - } - DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); + throw std::logic_error("phaseDensity() not implemented."); } /*! @@ -153,151 +146,41 @@ public: Scalar pressure, const FluidState &fluidState) { - if (phaseIdx == lPhaseIdx) { - // assume pure water for the liquid phase - // TODO: viscosity of mixture - return H2O::liquidViscosity(temperature, - pressure); - } - else { - return N2::gasViscosity(temperature, - pressure); - /* Wilke method. See: - * - * S.O.Ochs: "Development of a multiphase multicomponent - * model for PEMFC - Technical report: IRTG-NUPUS", - * University of Stuttgart, 2008 - * - * and: - * - * See: R. Reid, et al.: The Properties of Gases and Liquids, 4th - * edition, McGraw-Hill, 1987, 407-410 - */ - Scalar muResult = 0; - const Scalar mu[numComponents] = { - H2O::gasViscosity(temperature, - H2O::vaporPressure(temperature)), - N2::gasViscosity(temperature, - pressure) - }; - // molar masses - const Scalar M[numComponents] = { - H2O::molarMass(), - N2::molarMass() - }; - - for (int i = 0; i < numComponents; ++i) { - Scalar divisor = 0; - for (int j = 0; j < numComponents; ++j) { - Scalar phiIJ = 1 + sqrt(mu[i]/mu[j] * - pow(M[i]/M[j], 1/4.0)); - phiIJ *= phiIJ; - phiIJ /= sqrt(8*(1 + M[i]/M[j])); - divisor += fluidState.moleFrac(phaseIdx, j)*phiIJ; - } - muResult += fluidState.moleFrac(phaseIdx, i)*mu[i] / divisor; - } - - return muResult; - } + throw std::logic_error("phaseViscosity() not implemented."); } /*! - * \brief Assuming the composition of a single phase and the - * pressure of all phases is known or that all phases are - * present, compute the thermodynamic equilibrium from the - * temperature and phase pressures. If the known phase - * index - * + * \brief Assuming the surface volumes and the pressure of all + * phases are known, compute the phase volumes and + * saturations. */ template - static void computeEquilibrium(FluidState &fluidState, - int knownPhaseIdx = -1) + static void computeEquilibrium(FluidState& fluid_state) { - const Scalar T = fluidState.temperature(); - const Scalar pg = fluidState.phasePressure(gPhaseIdx); - const Scalar pl = fluidState.phasePressure(lPhaseIdx); + // Get B and R factors. + const double* p = fluid_state.phase_pressure_; + const double* z = fluid_state.surface_volume_; + double B[3]; + B[Aqua] = params().pvt_.B(p[Aqua], z, Aqua); + B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); + B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); + double R[3]; // Only using 2 of them, though. + R[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); + R[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); - const Scalar betaH2O = H2O::vaporPressure(T); - const Scalar betaN2 = BinaryCoeff::H2O_N2::henry(T); + // Update phase volumes. + double* u = fluid_state.phase_volume_; + double detR = 1.0 - R[Vapour]*R[Liquid]; + u[Aqua] = B[Aqua]*z[Water]; + u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; + u[Liquid] = B[Aqua]*(z[Oil] - R[Vapour]*z[Gas])/detR; - if (knownPhaseIdx < 0) - { - // we only have all phase pressures and temperature and - // know that all phases are present - Scalar xlH2O = (pg - betaN2)/(betaH2O - betaN2); - Scalar xlN2 = 1 - xlH2O; - Scalar rhol = liquidPhaseDensity_(T, pl, xlH2O, xlN2); - - Scalar cgH2O = H2O::gasDensity(T, betaH2O*xlH2O)/H2O::molarMass(); - Scalar cgN2 = N2::gasDensity(T, betaN2*xlN2)/N2::molarMass(); - - Scalar xgH2O = cgH2O/(cgH2O + cgN2); - Scalar xgN2 = cgN2/(cgH2O + cgN2); - - // set the liquid phase composition - SettablePhase liquid; - liquid.moleFrac_[H2OIdx] = xlH2O; - liquid.moleFrac_[N2Idx] = xlN2; - liquid.pressure_ = pl; - liquid.density_ = rhol; - liquid.xToX(); // compute mass fractions from mole fractions - fluidState.assignPhase(lPhaseIdx, liquid); - - // set the gas phase composition - SettablePhase gas; - gas.moleFrac_[H2OIdx] = xgH2O; - gas.moleFrac_[N2Idx] = xgN2; - gas.pressure_ = pg; - gas.density_ = cgH2O*H2O::molarMass() + cgN2*N2::molarMass(); - gas.xToX(); // compute mass fractions from mole fractions - fluidState.assignPhase(gPhaseIdx, gas); - } - else if (knownPhaseIdx == lPhaseIdx) { - // the composition of the liquid phase is given - - // retrieve the known mole fractions from the fluid state - Scalar xlH2O = fluidState.moleFrac(lPhaseIdx, H2OIdx); - Scalar xlN2 = fluidState.moleFrac(lPhaseIdx, N2Idx); - - // calculate the component contentrations in the gas phase - Scalar pH2O = betaH2O*xlH2O; // fugacity of water - Scalar pN2 = betaN2*xlN2; // fugacity of nitrogen - Scalar cgH2O = H2O::gasDensity(T, pH2O)/H2O::molarMass(); - Scalar cgN2 = N2::gasDensity(T, pN2)/N2::molarMass(); - - // convert concentrations to mole fractions - Scalar xgH2O = cgH2O/(cgH2O + cgN2) * (pH2O + pN2)/pg; - Scalar xgN2 = cgN2/(cgH2O + cgN2) * (pH2O + pN2)/pg; - - // set gas phase composition - SettablePhase gas; - gas.moleFrac_[H2OIdx] = xgH2O; - gas.moleFrac_[N2Idx] = xgN2; - gas.pressure_ = pg; - gas.density_ = cgH2O*H2O::molarMass() + cgN2*N2::molarMass(); - gas.xToX(); // update mass fractions from mole fractions - fluidState.assignPhase(gPhaseIdx, gas); - } - else if (knownPhaseIdx == gPhaseIdx) { - // the composition of the gas phase is given - - Scalar xgH2O = fluidState.moleFrac(gPhaseIdx, H2OIdx); - Scalar xgN2 = fluidState.moleFrac(gPhaseIdx, N2Idx); - Scalar pgH2O = pg*xgH2O; - Scalar pgN2 = pg*xgN2; - - Scalar xlH2O = pgH2O/betaH2O; - Scalar xlN2 = pgN2/betaN2; - - SettablePhase liquid; - liquid.moleFrac_[H2OIdx] = xlH2O; - liquid.moleFrac_[N2Idx] = xlN2; - liquid.pressure_ = pl; - liquid.density_ = liquidPhaseDensity_(T, pl, xlH2O, xlN2); - liquid.xToX(); // update mass fractions from mole fractions - fluidState.assignPhase(lPhaseIdx, liquid); + // Update saturations. + double sumu = u[Aqua] + u[Vapour] + u[Liquid]; + double* s = fluid_state.saturation_; + for (int i = 0; i < 3; ++i) { + s[i] = u[i]/sumu; } } @@ -326,28 +209,8 @@ public: Scalar pressure, const FluidState &state) { - if (phaseIdx == gPhaseIdx) { - return pressure; - Scalar fugH2O = std::max(1e-3, state.fugacity(H2OIdx)); - Scalar fugN2 = std::max(1e-3, state.fugacity(N2Idx)); - Scalar cH2O = H2O::gasDensity(temperature, fugH2O) / H2O::molarMass(); - Scalar cN2 = N2::gasDensity(temperature, fugN2) / N2::molarMass(); - - Scalar alpha = (fugH2O + fugN2)/pressure; - - if (compIdx == H2OIdx) - return fugH2O/(alpha*cH2O/(cH2O + cN2)); - else if (compIdx == N2Idx) - return fugN2/(alpha*cN2/(cH2O + cN2)); - - DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); - } - - switch (compIdx) { - case H2OIdx: return H2O::vaporPressure(temperature); - case N2Idx: return BinaryCoeff::H2O_N2::henry(temperature); - }; - DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); + throw std::logic_error("activityCoeff() not implemented."); + return 0.0; } /*! @@ -363,49 +226,8 @@ public: Scalar pressure, const FluidState &fluidState) { - if (compIIdx > compJIdx) - std::swap(compIIdx, compJIdx); - -#ifndef NDEBUG - if (compIIdx == compJIdx || - phaseIdx > numPhases - 1 || - compJIdx > numComponents - 1) - { - DUNE_THROW(Dune::InvalidStateException, - "Binary diffusion coefficient of components " - << compIIdx << " and " << compJIdx - << " in phase " << phaseIdx << " is undefined!\n"); - } -#endif - - - switch (phaseIdx) { - case lPhaseIdx: - switch (compIIdx) { - case H2OIdx: - switch (compJIdx) { - case N2Idx: return BinaryCoeff::H2O_N2::liquidDiffCoeff(temperature, - pressure); - } - default: - DUNE_THROW(Dune::InvalidStateException, - "Binary diffusion coefficients of trace " - "substances in liquid phase is undefined!\n"); - } - case gPhaseIdx: - switch (compIIdx) { - case H2OIdx: - switch (compJIdx) { - case N2Idx: return BinaryCoeff::H2O_N2::gasDiffCoeff(temperature, - pressure); - } - } - } - - DUNE_THROW(Dune::InvalidStateException, - "Binary diffusion coefficient of components " - << compIIdx << " and " << compJIdx - << " in phase " << phaseIdx << " is undefined!\n"); + throw std::logic_error("diffCoeff() not implemented."); + return 0.0; }; /*! @@ -418,35 +240,8 @@ public: Scalar pressure, const FluidState &fluidState) { - if (phaseIdx == lPhaseIdx) { - Scalar cN2 = fluidState.concentration(lPhaseIdx, N2Idx); - Scalar pN2 = N2::gasPressure(temperature, cN2*N2::molarMass()); - - // TODO: correct way to deal with the solutes??? - return - fluidState.massFrac(lPhaseIdx, H2OIdx)* - H2O::liquidEnthalpy(temperature, pressure) - + - fluidState.massFrac(lPhaseIdx, N2Idx)* - N2::gasEnthalpy(temperature, pN2); - } - else { - Scalar cH2O = fluidState.concentration(gPhaseIdx, H2OIdx); - Scalar cN2 = fluidState.concentration(gPhaseIdx, N2Idx); - - Scalar pH2O = H2O::gasPressure(temperature, cH2O*H2O::molarMass()); - Scalar pN2 = N2::gasPressure(temperature, cN2*N2::molarMass()); - - Scalar result = 0; - result += - H2O::gasEnthalpy(temperature, pH2O) * - fluidState.massFrac(gPhaseIdx, H2OIdx); - result += - N2::gasEnthalpy(temperature, pN2) * - fluidState.massFrac(gPhaseIdx, N2Idx); - - return result; - } + throw std::logic_error("phaseEnthalpy() not implemented."); + return 0.0; } /*! @@ -459,33 +254,11 @@ public: Scalar pressure, const FluidState &fluidState) { - return - phaseEnthalpy(phaseIdx, temperature, pressure, fluidState) - - pressure/phaseDensity(phaseIdx, temperature, pressure, fluidState); + throw std::logic_error("phaseInternalEnergy() not implemented."); + return 0.0; } private: - static Scalar liquidPhaseDensity_(Scalar T, Scalar pl, Scalar xlH2O, Scalar xlN2) - { - // See: Ochs 2008 - // \todo: proper citation - Scalar rholH2O = H2O::liquidDensity(T, pl); - Scalar clH2O = rholH2O/H2O::molarMass(); - - // this assumes each nitrogen molecule displaces exactly one - // water molecule in the liquid - return - clH2O*(xlH2O*H2O::molarMass() - + - xlN2*N2::molarMass()); - } - - static Scalar gasPhaseDensity_(Scalar T, Scalar pg, Scalar xgH2O, Scalar xgN2) - { - return H2O::gasDensity(T, pg*xgH2O) + N2::gasDensity(T, pg*xgN2); - }; - -#endif static Params& params() { diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index e532e211..66708868 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -36,6 +36,7 @@ #include "MiscibilityProps.hpp" #include +#include // Forward declaration. class PVTW; @@ -46,24 +47,26 @@ namespace Opm { public: typedef std::vector > table_t; - MiscibilityWater(const table_t& pvtw) + MiscibilityWater(const table_t& pvtw, const Dune::EclipseUnits& units) { const int region_number = 0; if (pvtw.size() != 1) { THROW("More than one PVD-region"); } - double b = pvtw[region_number][1]; - double comp = pvtw[region_number][2]; - double visc = pvtw[region_number][3]; - const double VISCOSITY_UNIT = 1e-3; - if (b == 1.0 && comp == 0) { - viscosity_ = visc*VISCOSITY_UNIT; - } else { - THROW("Compressible water not implemented."); + using namespace Dune::unit; + ref_press_ = convert::from(pvtw[region_number][0], units.pressure); + ref_B_ = convert::from(pvtw[region_number][1], units.liqvol_r/units.liqvol_s); + comp_ = convert::from(pvtw[region_number][2], units.compressibility); + viscosity_ = convert::from(pvtw[region_number][3], units.viscosity); + if (pvtw[region_number].size() > 4 && pvtw[region_number][4] != 0.0) { + THROW("MiscibilityWater does not support 'viscosibility'."); } } MiscibilityWater(double visc) - : viscosity_(visc) + : ref_press_(0.0), + ref_B_(1.0), + comp_(0.0), + viscosity_(visc) { } virtual ~MiscibilityWater() @@ -91,6 +94,9 @@ namespace Opm return 0.0; } private: + double ref_press_; + double ref_B_; + double comp_; double viscosity_; }; From 01424b12bfd243e89a57fccbdb02a7d7518dcda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 15 Nov 2010 12:41:21 +0100 Subject: [PATCH 014/113] Working on proper units. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 8 +++---- .../porsol/blackoil/fluid/MiscibilityDead.cpp | 10 ++++----- .../porsol/blackoil/fluid/MiscibilityDead.hpp | 4 +++- .../blackoil/fluid/MiscibilityLiveGas.cpp | 22 ++++++++++--------- .../blackoil/fluid/MiscibilityLiveGas.hpp | 3 ++- .../blackoil/fluid/MiscibilityLiveOil.cpp | 2 +- .../blackoil/fluid/MiscibilityLiveOil.hpp | 3 ++- .../blackoil/fluid/MiscibilityWater.hpp | 19 ++++++++++++---- 8 files changed, 44 insertions(+), 27 deletions(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index 4df2ced7..e568534c 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -61,18 +61,18 @@ namespace Opm // Oil PVT if (parser.hasField("PVDO")) { - oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_)); + oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_, parser.units())); } else if (parser.hasField("PVTO")) { - oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_)); + oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_, parser.units())); } else { THROW("Input is missing PVDO and PVTO\n"); } // Gas PVT if (parser.hasField("PVDG")) { - gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_)); + gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_, parser.units())); } else if (parser.hasField("PVTG")) { - gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_)); + gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_, parser.units())); } else { THROW("Input is missing PVDG and PVTG\n"); } diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 435fd034..e1e98645 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -32,6 +32,7 @@ #include "MiscibilityDead.hpp" #include #include +#include using namespace std; using namespace Dune; @@ -44,7 +45,7 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityDead::MiscibilityDead(const table_t& pvd_table) + MiscibilityDead::MiscibilityDead(const table_t& pvd_table, const Dune::EclipseUnits& units) : pvdx_(pvd_table) { const int region_number = 0; @@ -52,12 +53,11 @@ namespace Opm THROW("More than one PVT-region"); } // Convert units - const double bar = 1e5; - const double VISCOSITY_UNIT = 1e-3; const int sz = pvdx_[region_number][0].size(); + using namespace Dune::unit; for (int i=0; i + namespace Opm { @@ -44,7 +46,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityDead(const table_t& pvd_table); + MiscibilityDead(const table_t& pvd_table, const Dune::EclipseUnits& units); virtual ~MiscibilityDead(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp index 047af829..d2806bb8 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -33,6 +33,7 @@ #include "MiscibilityLiveGas.hpp" #include #include +#include using namespace std; using namespace Dune; @@ -45,11 +46,9 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg) + MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg, const EclipseUnits& units) { // GAS, PVTG - const double bar = 1e5; - const double VISCOSITY_UNIT = 1e-3; const int region_number = 0; if (pvtg.size() != 1) { THROW("More than one PVD-region"); @@ -59,11 +58,14 @@ namespace Opm for (int k=0; k<4; ++k) { saturated_gas_table_[k].resize(sz); } + using namespace Dune::unit; + const double bunit = units.gasvol_r/units.gasvol_s; + const double runit = units.liqvol_s/units.gasvol_s; for (int i=0; i namespace Opm { @@ -44,7 +45,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityLiveGas(const table_t& pvto); + MiscibilityLiveGas(const table_t& pvto, const Dune::EclipseUnits& units); virtual ~MiscibilityLiveGas(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index ab5a0f58..8558ec20 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -45,7 +45,7 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto) + MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto, const EclipseUnits& units) { // OIL, PVTO const double bar = 1e5; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp index fb3abdd0..87937cdb 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -36,6 +36,7 @@ */ #include "MiscibilityProps.hpp" +#include namespace Opm { @@ -44,7 +45,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityLiveOil(const table_t& pvto); + MiscibilityLiveOil(const table_t& pvto, const Dune::EclipseUnits& units); virtual ~MiscibilityLiveOil(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index 66708868..af25ab32 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -37,6 +37,7 @@ #include "MiscibilityProps.hpp" #include #include +#include // Forward declaration. class PVTW; @@ -77,13 +78,23 @@ namespace Opm { return viscosity_; } - virtual double B(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + virtual double B(int /*region*/, double press, const surfvol_t& /*surfvol*/) const { - return 1.0; + if (comp_) { + // Computing a polynomial approximation to the exponential. + double x = comp_*(press - ref_press_); + return ref_B_/(1.0 + x + 0.5*x*x); + } else { + return ref_B_; + } } - virtual double dBdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const { - return 0.0; + if (comp_) { + return comp_*B(region, press, surfvol); + } else { + return 0.0; + } } virtual double R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const { From db6da9443b3bd8914d84bbc0a3988646e0904cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 15 Nov 2010 12:48:10 +0100 Subject: [PATCH 015/113] Done accounting for units in PVT, relperm and pc tables. --- .../fluid/FluidMatrixInteractionBlackoil.hpp | 25 +------------------ .../blackoil/fluid/MiscibilityLiveOil.cpp | 20 ++++++++------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp index f341dca6..e5992e0c 100644 --- a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -72,21 +72,7 @@ public: // Create tables for pcow and pcog. // We must convert the pressures depending on units. - double pressure_unit = 0.0; - switch (unitsInParser(ep)) { - case Metric: - pressure_unit = Dune::unit::barsa; - break; - case Field: - pressure_unit = Dune::unit::psia; - break; - case Lab: - case Pvtm: - pressure_unit = Dune::unit::atm; - break; - default: - throw std::logic_error("Unknown unit system."); - } + double pressure_unit = ep.units().pressure; int numw = sw.size(); std::vector pcow(numw); for (int i = 0; i < numw; ++i) { @@ -112,15 +98,6 @@ private: Dune::utils::UniformTableLinear krog_; Dune::utils::UniformTableLinear pcog_; Scalar krocw_; // = krow_(s_wc) - - enum EclipseUnitFamily { Metric = 0, Field = 1, Lab = 2, Pvtm = 3 }; - EclipseUnitFamily unitsInParser(const Dune::EclipseGridParser& ep) - { - if (ep.hasField("FIELD")) return Field; - if (ep.hasField("LAB")) return Lab; - if (ep.hasField("PVT-M")) return Pvtm; - return Metric; // The default. - } }; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 8558ec20..391b325d 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -32,6 +32,7 @@ #include "MiscibilityLiveOil.hpp" #include #include +#include using namespace std; using namespace Dune; @@ -48,8 +49,6 @@ namespace Opm MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto, const EclipseUnits& units) { // OIL, PVTO - const double bar = 1e5; - const double VISCOSITY_UNIT = 1e-3; const int region_number = 0; if (pvto.size() != 1) { THROW("More than one PVD-region"); @@ -59,11 +58,14 @@ namespace Opm for (int k=0; k<4; ++k) { saturated_oil_table_[k].resize(sz); } + using namespace Dune::unit; + const double bunit = units.liqvol_r/units.liqvol_s; + const double runit = units.gasvol_s/units.liqvol_s; for (int i=0; i Date: Mon, 15 Nov 2010 20:11:45 +0100 Subject: [PATCH 016/113] Moved common enums for phase names etc. to BlackoilDefs helper class. --- dune/porsol/blackoil/fluid/BlackoilDefs.hpp | 38 +++ dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 5 +- .../fluid/FluidMatrixInteractionBlackoil.hpp | 5 +- .../blackoil/fluid/FluidStateBlackoil.hpp | 240 +++--------------- .../blackoil/fluid/MiscibilityProps.hpp | 4 +- 5 files changed, 79 insertions(+), 213 deletions(-) create mode 100644 dune/porsol/blackoil/fluid/BlackoilDefs.hpp diff --git a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp new file mode 100644 index 00000000..3a38d8ae --- /dev/null +++ b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp @@ -0,0 +1,38 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_BLACKOILDEFS_HEADER_INCLUDED +#define OPM_BLACKOILDEFS_HEADER_INCLUDED + +namespace Opm +{ + + class BlackoilDefs + { + public: + enum { numComponents = 3 }; + enum { numPhases = 3 }; + + enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; + enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + }; + +} // namespace Opm + +#endif // OPM_BLACKOILDEFS_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp index dd97c590..1f5156d4 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -22,6 +22,7 @@ #include "MiscibilityProps.hpp" +#include "BlackoilDefs.hpp" #include #include #include @@ -29,13 +30,11 @@ namespace Opm { - class BlackoilPVT + class BlackoilPVT : public BlackoilDefs { public: typedef MiscibilityProps::surfvol_t surfvol_t; - enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; - void init(const Dune::EclipseGridParser& ep); double getViscosity(double press, const surfvol_t& surfvol, diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp index e5992e0c..91cbb9a0 100644 --- a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -24,6 +24,7 @@ #include #include #include +#include "BlackoilDefs.hpp" #include #include @@ -107,13 +108,11 @@ private: * \brief Capillary pressures and relative permeabilities for a black oil system. */ template > -class FluidMatrixInteractionBlackoil +class FluidMatrixInteractionBlackoil : public BlackoilDefs { public: typedef ParamsT Params; typedef typename Params::Scalar Scalar; - enum { numPhases = 3 }; - enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; /*! * \brief The linear capillary pressure-saturation curve. diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index bc7eb53d..79f296de 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -21,224 +21,54 @@ #define OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED -#include "" +#include "FluidSystemBlackoil.hpp" namespace Opm { -/*! - * \brief Calcultes the phase state from the primary variables in the - * blackoil model. - */ -class FluidStateBlackoil -{ -public: - enum { numPhases = 3 }; - enum { numComponents = 3}; - - typedef int FluidSystem; // TODO - typedef int PrimaryVars; // TODO - typedef double Scalar; - typedef FluidMatrixInteractionBlackoil MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; - /*! - * \brief Update the phase state from the primary variables. + * \brief Calculates the phase state from the primary variables in the + * blackoil model. */ - void update(const PrimaryVariables &primaryVars, - const MaterialLawParams &pcParams, - Scalar temperature) + struct FluidStateBlackoil : public BlackoilDefs { - // calculate the temperature - temperature_ = temperature; + typedef FluidSystemBlackoil FluidSystem; + typedef double Scalar; + typedef std::tr1::array PrimaryVariables; // Surface volumes and phase pressures. + typedef FluidMatrixInteractionBlackoil MaterialLaw; + typedef typename MaterialLaw::Params MaterialLawParams; - // calculate the saturations - saturation_[numPhases - 1] = 1.0; - for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) { - saturation_[phaseIdx] = primaryVars[S0Idx + phaseIdx]; - saturation_[numPhases - 1] -= saturation_[phaseIdx]; - } + Scalar temperature_; + Scalar surface_volume_[numComponents]; + Scalar phase_pressure_[numPhases]; + Scalar phase_volume_[numPhases]; + Scalar saturation_[numPhases]; - // let the material law calculate the capillary pressures - MaterialLaw::pC(phasePressure_, - pcParams, - saturation_, - temperature_); - // convert to phase pressures - Scalar sumPc = 0; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - sumPc += phasePressure_[phaseIdx]; - phasePressure_[phaseIdx] = primaryVars[p0Idx] - sumPc; - } - - updateComposition_(primaryVars); - } + /*! + * \brief Update the phase state from the primary variables. + */ + void update(const PrimaryVariables& primary_vars, + const MaterialLawParams& material_params, + Scalar temperature) + { + // Set the temperature. + temperature_ = temperature; -private: - void updateComposition_(const PrimaryVariables &primaryVars) - { - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - meanMolarMass_[phaseIdx] = 0; - } - - // extract the mole fractions in both phases - Scalar sumFuga = 0; - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - fugacity_[compIdx] = primaryVars[fug0Idx + compIdx]; - Valgrind::CheckDefined(fugacity_[compIdx]); - sumFuga += fugacity_[compIdx]; - - // convert the fugacities into mole fractions - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - moleFrac_[phaseIdx][compIdx] = - fugacity_[compIdx] / - FluidSystem::activityCoeff(phaseIdx, - compIdx, - temperature_, - phasePressure(phaseIdx), - *this); - Valgrind::CheckDefined(moleFrac_[phaseIdx][compIdx]); - - // update the mean molar mass of each phase - meanMolarMass_[phaseIdx] - += FluidSystem::molarMass(compIdx)*moleFrac_[phaseIdx][compIdx]; + // Set the surface volumes. + for (int i = 0; i < numComponents; ++i) { + surface_volume_[i] = primary_vars[i]; } + + // Set the phase pressures. + for (int i = 0; i < numPhases; ++i) { + phase_pressure_[i] = primary_vars[numComponents + i]; + } + + // Compute phase volumes by the fluid system rules. + FluidSystem::computeEquilibrium(*this); } - - // make sure that the primary variables do not represent an - // unphysical state! - if (sumFuga < 1e-30) { - DUNE_THROW(NumericalProblem, - "Sum of component fugacities is too small: " << sumFuga); - } - - // calculate the total concentration of each phase - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // make sure that the mean molar mass within a phase is - // not "way off" - if (std::abs(meanMolarMass_[phaseIdx]) < 1e-30) - DUNE_THROW(NumericalProblem, - "Mean molar mass of phase " - << phaseIdx - << " is too small (" - << meanMolarMass_[phaseIdx] - << ")\n" << primaryVars); - - // calculate the total concentration of the phase - phaseConcentration_[phaseIdx] = - FluidSystem::phaseDensity(phaseIdx, - temperature(), - phasePressure(phaseIdx), - *this) - / - meanMolarMass_[phaseIdx]; - } - - Valgrind::CheckDefined(fugacity_); - Valgrind::CheckDefined(moleFrac_); - Valgrind::CheckDefined(phaseConcentration_); - Valgrind::CheckDefined(meanMolarMass_); - Valgrind::CheckDefined(temperature_); - Valgrind::CheckDefined(phasePressure_); - Valgrind::CheckDefined(saturation_); - } - -public: - /*! - * \brief Returns the saturation of a phase. - */ - Scalar saturation(int phaseIdx) const - { return saturation_[phaseIdx]; } - - /*! - * \brief Returns a vector of all phase saturations. - */ - const Scalar *saturations() const - { return saturation_; } - - /*! - * \brief Returns the molar fraction of a component in a fluid phase. - */ - Scalar moleFrac(int phaseIdx, int compIdx) const - { return moleFrac_[phaseIdx][compIdx]; } - - /*! - * \brief Returns the total concentration of a phase [mol / m^3]. - * - * This is equivalent to the sum of all component concentrations. - */ - Scalar phaseConcentration(int phaseIdx) const - { return phaseConcentration_[phaseIdx]; }; - - /*! - * \brief Returns the concentration of a component in a phase [mol / m^3]. - */ - Scalar concentration(int phaseIdx, int compIdx) const - { return moleFrac_[phaseIdx][compIdx]*phaseConcentration_[phaseIdx]; }; - - /*! - * \brief Returns the mass fraction of a component in a phase. - */ - Scalar massFrac(int phaseIdx, int compIdx) const - { - return - moleFrac_[phaseIdx][compIdx]* - FluidSystem::molarMass(compIdx) - / - meanMolarMass_[phaseIdx]; - } - - /*! - * \brief Returns the density of a phase [kg / m^3]. - */ - Scalar density(int phaseIdx) const - { return phaseConcentration_[phaseIdx]*meanMolarMass_[phaseIdx]; } - - /*! - * \brief Returns mean molar mass of a phase [kg / mol]. - * - * This is equivalent to the sum of all component molar masses - * weighted by their respective mole fraction. - */ - Scalar meanMolarMass(int phaseIdx) const - { return meanMolarMass_[phaseIdx]; }; - - /*! - * \brief Returns the fugacity of a component [Pa]. - */ - Scalar fugacity(int compIdx) const - { return fugacity_[compIdx]; } - - /*! - * \brief Returns the pressure of a fluid phase [Pa]. - */ - Scalar phasePressure(int phaseIdx) const - { return phasePressure_[phaseIdx]; } - - /*! - * \brief Returns the capillary pressure [Pa] - */ - Scalar capillaryPressure(int phaseIdx) const - { return phasePressure_[0] - phasePressure_[phaseIdx]; } - - /*! - * \brief Returns the temperature of the fluids [K]. - * - * Note that we assume thermodynamic equilibrium, so all fluids - * and the rock matrix exhibit the same temperature. - */ - Scalar temperature() const - { return temperature_; }; - -public: - Scalar temperature_; - Scalar surface_volume_[numComponents]; - Scalar phase_pressure_[numPhases]; - Scalar phase_volume_[numPhases]; - Scalar saturation_[numPhases]; -}; + }; } // end namespace Opm diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp index 7d0ba2c5..588c5e0f 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -35,6 +35,7 @@ * Detailed description. */ +#include "BlackoilDefs.hpp" #include #include @@ -42,11 +43,10 @@ namespace Opm { - class MiscibilityProps + class MiscibilityProps : public BlackoilDefs { public: typedef std::tr1::array surfvol_t; - enum PhaseNames { Aqua = 0, Liquid = 1, Vapour = 2 }; MiscibilityProps(); virtual ~MiscibilityProps(); From 65a6604112f500391d84db2d4f8b25ae62d5bd88 Mon Sep 17 00:00:00 2001 From: Ove Saevareid Date: Mon, 22 Nov 2010 13:07:24 +0100 Subject: [PATCH 017/113] Oil relperm: krocw_ evaluated at connate water, krow at sw. --- .../blackoil/fluid/FluidMatrixInteractionBlackoil.hpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp index 91cbb9a0..798f1b6e 100644 --- a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -64,12 +64,7 @@ public: buildUniformMonotoneTable(sw, krow, samples, krow_); buildUniformMonotoneTable(sg, krg, samples, krg_); buildUniformMonotoneTable(sg, krog, samples, krog_); - for (int i = 0; i < int(krw.size()); ++i) { - if (krw[i] > 0.0) { - krocw_ = krow[i]; - break; - } - } + krocw_ = krow[0]; // At connate water -> ecl. SWOF // Create tables for pcow and pcog. // We must convert the pressures depending on units. @@ -174,7 +169,7 @@ public: Scalar so = saturations[Liquid]; Scalar krw = params.krw_(sw); Scalar krg = params.krg_(sg); - Scalar krow = params.krow_(so); + Scalar krow = params.krow_(sw); Scalar krog = params.krog_(sg); Scalar krocw = params.krocw_; kr[Aqua] = krw; From 6dae6341419f1adaea0c63421e5215b0dc32e139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 22 Nov 2010 15:00:26 +0100 Subject: [PATCH 018/113] A large number of additions to start testing compressible tpfa-solver. --- dune/porsol/blackoil/BlackoilFluid.hpp | 68 +++++++++++++++++++ dune/porsol/blackoil/fluid/BlackoilDefs.hpp | 8 +++ dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 12 ++-- dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 21 +++--- .../blackoil/fluid/FluidStateBlackoil.hpp | 48 +++---------- .../blackoil/fluid/FluidSystemBlackoil.hpp | 43 +++++++----- .../blackoil/fluid/MiscibilityProps.hpp | 2 +- 7 files changed, 130 insertions(+), 72 deletions(-) create mode 100644 dune/porsol/blackoil/BlackoilFluid.hpp diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp new file mode 100644 index 00000000..914ceb6b --- /dev/null +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -0,0 +1,68 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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_BLACKOILFLUID_HEADER_INCLUDED +#define OPM_BLACKOILFLUID_HEADER_INCLUDED + + +#include +#include +#include +#include +#include + + +namespace Opm +{ + + class BlackoilFluid + { + public: + enum { numPhases = 3 }; + enum { numComponents = 3 }; + typedef Dune::FieldVector PhaseVec; + typedef Dune::FieldVector CompVec; + + void init(const Dune::EclipseGridParser& parser) + { + fmi_params_.init(parser); + FluidSystemBlackoil<>::init(parser); + } + + FluidStateBlackoil computeState(PhaseVec phase_pressure, CompVec z) + { + FluidStateBlackoil state; + state.temperature_ = 300; + state.phase_pressure_ = phase_pressure; + state.surface_volume_ = z; + FluidSystemBlackoil<>::computeEquilibrium(state); // Sets everything but relperm and mobility. + FluidMatrixInteractionBlackoil::kr(state.relperm_, fmi_params_, state.saturation_, state.temperature_); + for (int phase = 0; phase < numPhases; ++phase) { + state.mobility_[phase] = state.relperm_[phase]/state.viscosity_[phase]; + } + return state; + } + + private: + FluidMatrixInteractionBlackoilParams fmi_params_; + }; + +} // namespace Opm + +#endif // OPM_BLACKOILFLUID_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp index 3a38d8ae..c0cfe15b 100644 --- a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp @@ -20,6 +20,10 @@ #ifndef OPM_BLACKOILDEFS_HEADER_INCLUDED #define OPM_BLACKOILDEFS_HEADER_INCLUDED + +#include + + namespace Opm { @@ -31,6 +35,10 @@ namespace Opm enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + + typedef double Scalar; + typedef Dune::FieldVector CompVec; + typedef Dune::FieldVector PhaseVec; }; } // namespace Opm diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index e568534c..7ae03c6d 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -78,32 +78,32 @@ namespace Opm } } - BlackoilPVT::surfvol_t BlackoilPVT::surfaceDensities() const + BlackoilPVT::CompVec BlackoilPVT::surfaceDensities() const { return densities_; } - double BlackoilPVT::getViscosity(double press, const surfvol_t& surfvol, PhaseIndex phase) const + double BlackoilPVT::getViscosity(double press, const CompVec& surfvol, PhaseIndex phase) const { return propsForPhase(phase).getViscosity(region_number_, press, surfvol); } - double BlackoilPVT::B(double press, const surfvol_t& surfvol, PhaseIndex phase) const + double BlackoilPVT::B(double press, const CompVec& surfvol, PhaseIndex phase) const { return propsForPhase(phase).B(region_number_, press, surfvol); } - double BlackoilPVT::dBdp(double press, const surfvol_t& surfvol, PhaseIndex phase) const + double BlackoilPVT::dBdp(double press, const CompVec& surfvol, PhaseIndex phase) const { return propsForPhase(phase).dBdp(region_number_, press, surfvol); } - double BlackoilPVT::R(double press, const surfvol_t& surfvol, PhaseIndex phase) const + double BlackoilPVT::R(double press, const CompVec& surfvol, PhaseIndex phase) const { return propsForPhase(phase).R(region_number_, press, surfvol); } - double BlackoilPVT::dRdp(double press, const surfvol_t& surfvol, PhaseIndex phase) const + double BlackoilPVT::dRdp(double press, const CompVec& surfvol, PhaseIndex phase) const { return propsForPhase(phase).dRdp(region_number_, press, surfvol); } diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp index 1f5156d4..0563daab 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -33,20 +33,23 @@ namespace Opm class BlackoilPVT : public BlackoilDefs { public: - typedef MiscibilityProps::surfvol_t surfvol_t; - void init(const Dune::EclipseGridParser& ep); - double getViscosity(double press, const surfvol_t& surfvol, + double getViscosity(double press, + const CompVec& surfvol, PhaseIndex phase) const; - surfvol_t surfaceDensities() const; - double B (double press, const surfvol_t& surfvol, + CompVec surfaceDensities() const; + double B (double press, + const CompVec& surfvol, PhaseIndex phase) const; - double dBdp(double press, const surfvol_t& surfvol, + double dBdp(double press, + const CompVec& surfvol, PhaseIndex phase) const; - double R (double press, const surfvol_t& surfvol, + double R (double press, + const CompVec& surfvol, PhaseIndex phase) const; - double dRdp(double press, const surfvol_t& surfvol, + double dRdp(double press, + const CompVec& surfvol, PhaseIndex phase) const; @@ -57,7 +60,7 @@ namespace Opm boost::scoped_ptr water_props_; boost::scoped_ptr oil_props_; boost::scoped_ptr gas_props_; - surfvol_t densities_; + CompVec densities_; }; } diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 79f296de..da8e025e 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -21,53 +21,25 @@ #define OPM_FLUIDSTATEBLACKOIL_HEADER_INCLUDED -#include "FluidSystemBlackoil.hpp" +#include "BlackoilDefs.hpp" namespace Opm { /*! - * \brief Calculates the phase state from the primary variables in the - * blackoil model. + * \brief Fluid states for a black oil model. */ struct FluidStateBlackoil : public BlackoilDefs { - typedef FluidSystemBlackoil FluidSystem; - typedef double Scalar; - typedef std::tr1::array PrimaryVariables; // Surface volumes and phase pressures. - typedef FluidMatrixInteractionBlackoil MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; - Scalar temperature_; - Scalar surface_volume_[numComponents]; - Scalar phase_pressure_[numPhases]; - Scalar phase_volume_[numPhases]; - Scalar saturation_[numPhases]; - - - /*! - * \brief Update the phase state from the primary variables. - */ - void update(const PrimaryVariables& primary_vars, - const MaterialLawParams& material_params, - Scalar temperature) - { - // Set the temperature. - temperature_ = temperature; - - // Set the surface volumes. - for (int i = 0; i < numComponents; ++i) { - surface_volume_[i] = primary_vars[i]; - } - - // Set the phase pressures. - for (int i = 0; i < numPhases; ++i) { - phase_pressure_[i] = primary_vars[numComponents + i]; - } - - // Compute phase volumes by the fluid system rules. - FluidSystem::computeEquilibrium(*this); - } + CompVec surface_volume_; + PhaseVec phase_pressure_; + PhaseVec phase_volume_; + Scalar phase_to_comp_[numPhases*numComponents]; + PhaseVec saturation_; + PhaseVec viscosity_; + PhaseVec relperm_; + PhaseVec mobility_; }; } // end namespace Opm diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 6077bc1c..ccbcca18 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -35,6 +35,8 @@ #define OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED #include "BlackoilPVT.hpp" +#include "BlackoilDefs.hpp" +#include #include #include @@ -64,19 +66,10 @@ private: * \brief A black oil fluid system. */ template -class FluidSystemBlackoil +class FluidSystemBlackoil : public BlackoilDefs { public: typedef ParamsT Params; - typedef double Scalar; - - enum { numComponents = 3 }; - enum { numPhases = 3 }; - - enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; - enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; - - typedef BlackoilPVT::surfvol_t FluidVec; /*! * \brief Initialize system from input. @@ -151,16 +144,16 @@ public: /*! - * \brief Assuming the surface volumes and the pressure of all - * phases are known, compute the phase volumes and - * saturations. + * \brief Assuming the surface volumes and the pressures of all + * phases are known, compute everything except relperm and + * mobility. */ template static void computeEquilibrium(FluidState& fluid_state) { // Get B and R factors. - const double* p = fluid_state.phase_pressure_; - const double* z = fluid_state.surface_volume_; + const PhaseVec& p = fluid_state.phase_pressure_; + const CompVec& z = fluid_state.surface_volume_; double B[3]; B[Aqua] = params().pvt_.B(p[Aqua], z, Aqua); B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); @@ -168,9 +161,17 @@ public: double R[3]; // Only using 2 of them, though. R[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); R[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); + // Set the A matrix (A = RB^{-1}) + Dune::SharedFortranMatrix A(numComponents, numPhases, fluid_state.phase_to_comp_); + zero(A); + A(Water, Aqua) = 1.0/B[Aqua]; + A(Gas, Vapour) = 1.0/B[Vapour]; + A(Gas, Liquid) = R[Liquid]/B[Liquid]; + A(Oil, Vapour) = R[Vapour]/B[Vapour]; + A(Oil, Liquid) = 1.0/B[Liquid]; - // Update phase volumes. - double* u = fluid_state.phase_volume_; + // Update phase volumes. This is the same as multiplying with A^{-1} + PhaseVec& u = fluid_state.phase_volume_; double detR = 1.0 - R[Vapour]*R[Liquid]; u[Aqua] = B[Aqua]*z[Water]; u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; @@ -178,10 +179,16 @@ public: // Update saturations. double sumu = u[Aqua] + u[Vapour] + u[Liquid]; - double* s = fluid_state.saturation_; + PhaseVec& s = fluid_state.saturation_; for (int i = 0; i < 3; ++i) { s[i] = u[i]/sumu; } + + // Compute viscosities. + PhaseVec& mu = fluid_state.viscosity_; + mu[Aqua] = params().pvt_.getViscosity(p[Aqua], z, Aqua); + mu[Vapour] = params().pvt_.getViscosity(p[Vapour], z, Vapour); + mu[Liquid] = params().pvt_.getViscosity(p[Liquid], z, Liquid); } /*! diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp index 588c5e0f..693f87ec 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -46,7 +46,7 @@ namespace Opm class MiscibilityProps : public BlackoilDefs { public: - typedef std::tr1::array surfvol_t; + typedef CompVec surfvol_t; MiscibilityProps(); virtual ~MiscibilityProps(); From ebb352dc042e33ac8ee6a85c1896b636879fcb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 22 Nov 2010 15:00:26 +0100 Subject: [PATCH 019/113] A large number of additions to start testing compressible tpfa-solver. --- dune/porsol/common/UniformTableLinear.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dune/porsol/common/UniformTableLinear.hpp b/dune/porsol/common/UniformTableLinear.hpp index 8aa42d6b..644ad762 100644 --- a/dune/porsol/common/UniformTableLinear.hpp +++ b/dune/porsol/common/UniformTableLinear.hpp @@ -32,10 +32,6 @@ namespace Dune { namespace utils { - /// @brief Exception used for domain errors. - struct OutsideDomainException : public std::exception {}; - - /// @brief This class uses linear interpolation to compute the value /// (and its derivative) of a function f sampled at uniform points. /// @tparam T the range type of the function (should be an algebraic ring type) From 9ee3b6e3dec867973b37923f0cede40531478f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 23 Nov 2010 09:02:09 +0100 Subject: [PATCH 020/113] Tpfa tess compiles with BlackoilFluid. --- dune/porsol/blackoil/BlackoilFluid.hpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 914ceb6b..589479d3 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -31,13 +31,10 @@ namespace Opm { - class BlackoilFluid + class BlackoilFluid : public BlackoilDefs { public: - enum { numPhases = 3 }; - enum { numComponents = 3 }; - typedef Dune::FieldVector PhaseVec; - typedef Dune::FieldVector CompVec; + typedef FluidStateBlackoil FluidState; void init(const Dune::EclipseGridParser& parser) { @@ -45,9 +42,9 @@ namespace Opm FluidSystemBlackoil<>::init(parser); } - FluidStateBlackoil computeState(PhaseVec phase_pressure, CompVec z) + FluidState computeState(PhaseVec phase_pressure, CompVec z) const { - FluidStateBlackoil state; + FluidState state; state.temperature_ = 300; state.phase_pressure_ = phase_pressure; state.surface_volume_ = z; From e3bfe58574c20a0cf139f00a9178a6e22c1469b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 23 Nov 2010 09:39:37 +0100 Subject: [PATCH 021/113] Fixed a bug in the fluid code (getting B instead of A), handle zero liquid volume. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 4 ++-- dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index ccbcca18..127ae672 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -159,8 +159,8 @@ public: B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); double R[3]; // Only using 2 of them, though. - R[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); - R[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); + R[Vapour] = params().pvt_.R(p[Vapour], z, Vapour); + R[Liquid] = params().pvt_.R(p[Liquid], z, Liquid); // Set the A matrix (A = RB^{-1}) Dune::SharedFortranMatrix A(numComponents, numPhases, fluid_state.phase_to_comp_); zero(A); diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 391b325d..f88f2c94 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -125,13 +125,13 @@ namespace Opm double MiscibilityLiveOil::B(int /*region*/, double press, const surfvol_t& surfvol) const { - if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. + // if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. return 1.0/miscible_oil(press, surfvol, 1, false); } double MiscibilityLiveOil::dBdp(int region, double press, const surfvol_t& surfvol) const { - if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case. + // if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case. double Bo = B(region, press, surfvol); return -Bo*Bo*miscible_oil(press, surfvol, 1, true); } @@ -143,7 +143,7 @@ namespace Opm double R = linearInterpolationExtrap(saturated_oil_table_[0], saturated_oil_table_[3], press, section); - double maxR = surfvol[Vapour]/surfvol[Liquid]; + double maxR = (surfvol[Liquid] == 0.0) ? 0.0 : surfvol[Vapour]/surfvol[Liquid]; if (deriv) { if (R < maxR ) { // Saturated case return linearInterpolDerivative(saturated_oil_table_[0], From cf57ec6d1fd1d7a43120a59595c3db3af0a1fcbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 23 Nov 2010 16:18:20 +0100 Subject: [PATCH 022/113] Implemented compressibilities and volume discrepancies. Untested. --- .../blackoil/fluid/FluidStateBlackoil.hpp | 3 ++ .../blackoil/fluid/FluidSystemBlackoil.hpp | 32 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index da8e025e..f92a054c 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -35,8 +35,11 @@ namespace Opm CompVec surface_volume_; PhaseVec phase_pressure_; PhaseVec phase_volume_; + Scalar total_phase_volume_; Scalar phase_to_comp_[numPhases*numComponents]; PhaseVec saturation_; + PhaseVec phase_compressibility_; + Scalar total_compressibility_; PhaseVec viscosity_; PhaseVec relperm_; PhaseVec mobility_; diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 127ae672..276554d0 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -176,9 +176,10 @@ public: u[Aqua] = B[Aqua]*z[Water]; u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; u[Liquid] = B[Aqua]*(z[Oil] - R[Vapour]*z[Gas])/detR; + fluid_state.total_phase_volume_ = u[Aqua] + u[Vapour] + u[Liquid]; // Update saturations. - double sumu = u[Aqua] + u[Vapour] + u[Liquid]; + double sumu = fluid_state.total_phase_volume_; PhaseVec& s = fluid_state.saturation_; for (int i = 0; i < 3; ++i) { s[i] = u[i]/sumu; @@ -189,6 +190,35 @@ public: mu[Aqua] = params().pvt_.getViscosity(p[Aqua], z, Aqua); mu[Vapour] = params().pvt_.getViscosity(p[Vapour], z, Vapour); mu[Liquid] = params().pvt_.getViscosity(p[Liquid], z, Liquid); + + // Phase compressibilities. + PhaseVec& cp = fluid_state.phase_compressibility_; + double dB[3]; + dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); + dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); + dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); + double dR[3]; // Only using 2 of them, though. + dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); + dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); + // Set the derivative of the A matrix (A = RB^{-1}) + double data_for_dA[numComponents*numPhases]; + Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); + zero(dA); + dA(Water, Aqua) = -dB[Aqua]/(B[Aqua]*B[Aqua]); + dA(Gas, Vapour) = -dB[Vapour]/(B[Vapour]*B[Vapour]); + dA(Oil, Liquid) = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. + dA(Gas, Liquid) = dA(Oil, Liquid)*R[Liquid] + dR[Liquid]/B[Liquid]; + dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; + double data_for_Ai[numComponents*numPhases]; + Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); + Ai = A; + Dune::invert(Ai); + double data_for_C[numComponents*numPhases]; + Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); + Dune::prod(Ai, dA, C); + CompVec ones(1.0); + cp = Dune::prod(C, ones); + fluid_state.total_compressibility_ = cp*s; } /*! From 640dea22cddd3b9a191f91c120be47056f91c4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 24 Nov 2010 10:30:59 +0100 Subject: [PATCH 023/113] Fixed sign bug in dBdp function. --- dune/porsol/blackoil/fluid/MiscibilityWater.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index af25ab32..7cfb22b8 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -91,7 +91,7 @@ namespace Opm virtual double dBdp(int region, double press, const surfvol_t& surfvol) const { if (comp_) { - return comp_*B(region, press, surfvol); + return -comp_*B(region, press, surfvol); } else { return 0.0; } From e5525ce1c03ae534f0d1291770bf5a6ba140f6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 2 Dec 2010 13:28:36 +0100 Subject: [PATCH 024/113] Explicit copy matrix content after assignment semantics changed. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 276554d0..593080b7 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -211,7 +211,8 @@ public: dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; double data_for_Ai[numComponents*numPhases]; Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); - Ai = A; + // Ai = A; // This does not make a deep copy. + std::copy(A.data(), A.data() + numComponents*numPhases, Ai.data()); Dune::invert(Ai); double data_for_C[numComponents*numPhases]; Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); From bb0fc43b259288e503dde90154115ac0ffae7037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 6 Dec 2010 10:41:22 +0100 Subject: [PATCH 025/113] Refactoring in progress: moving fluid computations out of solvers. --- dune/porsol/blackoil/BlackoilFluid.hpp | 98 +++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 589479d3..d894dbfe 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -26,22 +26,30 @@ #include #include #include +#include namespace Opm { + + /// Forward declaration for typedef i BlackoilFluid. + class BlackoilFluidData; + + + /// Class responsible for computing all fluid properties from + /// face pressures and composition. class BlackoilFluid : public BlackoilDefs { public: typedef FluidStateBlackoil FluidState; + typedef BlackoilFluidData FluidData; void init(const Dune::EclipseGridParser& parser) { fmi_params_.init(parser); FluidSystemBlackoil<>::init(parser); } - FluidState computeState(PhaseVec phase_pressure, CompVec z) const { FluidState state; @@ -55,11 +63,97 @@ namespace Opm } return state; } - private: FluidMatrixInteractionBlackoilParams fmi_params_; }; + + + + /// Container for all fluid data needed by solvers. + struct BlackoilFluidData : public BlackoilDefs + { + std::vector totcompr; + std::vector totphasevol; + std::vector cellA; + std::vector faceA; + std::vector phasemobf; + private: + std::vector phasemobc; // Just a helper. + + public: + template + void compute(const Grid& grid, + const BlackoilFluid& fluid, + const std::vector& phase_pressure, + const std::vector& phase_pressure_face, + const std::vector& z, + const CompVec& bdy_z) + { + int num_cells = z.size(); + ASSERT(num_cells == grid.numCells()); + int num_faces = phase_pressure_face.size(); + ASSERT(num_faces == grid.numFaces()); + const int np = numPhases; + const int nc = numComponents; + BOOST_STATIC_ASSERT(np == nc); + totcompr.resize(num_cells); + totphasevol.resize(num_cells); + cellA.resize(num_cells*nc*np); + faceA.resize(num_faces*nc*np); + phasemobf.resize(np*num_faces); + phasemobc.resize(num_cells); + PhaseVec mob; + BOOST_STATIC_ASSERT(np == 3); + for (int cell = 0; cell < num_cells; ++cell) { + FluidStateBlackoil state = fluid.computeState(phase_pressure[cell], z[cell]); + totcompr[cell] = state.total_compressibility_; + totphasevol[cell] = state.total_phase_volume_; + phasemobc[cell] = state.mobility_; + std::copy(state.phase_to_comp_, state.phase_to_comp_ + nc*np, &cellA[cell*nc*np]); + } + // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. + // Set faceA by using average of cells' z and face pressures. + for (int face = 0; face < num_faces; ++face) { + int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; + PhaseVec phase_p[2]; + CompVec z_face(0.0); + int num = 0; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + phase_p[j] = phase_pressure[c[j]]; + z_face += z[c[j]]; + ++num; + } else { + // Boundaries get essentially -inf pressure for upwinding purpose. \TODO handle BCs. + phase_p[j] = PhaseVec(-1e100); + // \TODO The two lines below are wrong for outflow faces. + z_face += bdy_z; + ++num; + } + } + z_face /= double(num); + for (int phase = 0; phase < np; ++phase) { + if (phase_p[0][phase] == phase_p[1][phase]) { + // Average mobilities. + double aver = 0.5*(phasemobc[c[0]][phase] + phasemobc[c[1]][phase]); + phasemobf[np*face + phase] = aver; + } else { + // Upwind mobilities. + int upwind = (phase_p[0][phase] > phase_p[1][phase]) ? 0 : 1; + phasemobf[np*face + phase] = phasemobc[c[upwind]][phase]; + } + } + FluidStateBlackoil face_state = fluid.computeState(phase_pressure_face[face], z_face); + std::copy(face_state.phase_to_comp_, face_state.phase_to_comp_ + nc*np, &faceA[face*nc*np]); + } + + } + }; + + + + } // namespace Opm #endif // OPM_BLACKOILFLUID_HEADER_INCLUDED From 3df3114453b523e4f78da50fa63603b25b2bb174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 6 Dec 2010 11:09:30 +0100 Subject: [PATCH 026/113] Added comment. --- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index f92a054c..f359e890 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -36,7 +36,7 @@ namespace Opm PhaseVec phase_pressure_; PhaseVec phase_volume_; Scalar total_phase_volume_; - Scalar phase_to_comp_[numPhases*numComponents]; + Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering PhaseVec saturation_; PhaseVec phase_compressibility_; Scalar total_compressibility_; From d1a390a136cf30a798b46bc345b82b194d5be0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 6 Dec 2010 11:09:52 +0100 Subject: [PATCH 027/113] Added more data (for transport) and comments. --- dune/porsol/blackoil/BlackoilFluid.hpp | 32 +++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index d894dbfe..1ff3b771 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -73,13 +73,19 @@ namespace Opm /// Container for all fluid data needed by solvers. struct BlackoilFluidData : public BlackoilDefs { - std::vector totcompr; - std::vector totphasevol; - std::vector cellA; - std::vector faceA; - std::vector phasemobf; + // Per-cell data. + std::vector totcompr; // Total compressibility. + std::vector totphasevol; // Total volume filled by fluid phases. + std::vector cellA; // A = RB^{-1}. Fortran ordering, flat storage. + std::vector saturation; // Saturation. + std::vector frac_flow; // Fractional flow. + std::vector rel_perm; // Relative permeability. + std::vector viscosity; // Viscosity. + // Per-face data. + std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. + std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). private: - std::vector phasemobc; // Just a helper. + std::vector phasemobc; // Just a helper. Mobilities per cell. public: template @@ -99,6 +105,10 @@ namespace Opm BOOST_STATIC_ASSERT(np == nc); totcompr.resize(num_cells); totphasevol.resize(num_cells); + saturation.resize(num_cells); + frac_flow.resize(num_cells); + rel_perm.resize(num_cells); + viscosity.resize(num_cells); cellA.resize(num_cells*nc*np); faceA.resize(num_faces*nc*np); phasemobf.resize(np*num_faces); @@ -109,8 +119,18 @@ namespace Opm FluidStateBlackoil state = fluid.computeState(phase_pressure[cell], z[cell]); totcompr[cell] = state.total_compressibility_; totphasevol[cell] = state.total_phase_volume_; + saturation[cell] = state.saturation_; + rel_perm[cell] = state.relperm_; + viscosity[cell] = state.viscosity_; phasemobc[cell] = state.mobility_; std::copy(state.phase_to_comp_, state.phase_to_comp_ + nc*np, &cellA[cell*nc*np]); + // Fractional flow must be calculated. + double total_mobility = 0.0; + for (int phase = 0; phase < numPhases; ++phase) { + total_mobility += state.mobility_[phase]; + } + frac_flow[cell] = state.mobility_; + frac_flow[cell] /= total_mobility; } // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. // Set faceA by using average of cells' z and face pressures. From c7b180de7b180789f52e401939ca6e9286ffabba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 6 Dec 2010 15:11:47 +0100 Subject: [PATCH 028/113] Variable renaming. --- dune/porsol/blackoil/BlackoilFluid.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 1ff3b771..53981767 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -91,14 +91,14 @@ namespace Opm template void compute(const Grid& grid, const BlackoilFluid& fluid, - const std::vector& phase_pressure, - const std::vector& phase_pressure_face, + const std::vector& cell_pressure, + const std::vector& face_pressure, const std::vector& z, const CompVec& bdy_z) { int num_cells = z.size(); ASSERT(num_cells == grid.numCells()); - int num_faces = phase_pressure_face.size(); + int num_faces = face_pressure.size(); ASSERT(num_faces == grid.numFaces()); const int np = numPhases; const int nc = numComponents; @@ -116,7 +116,7 @@ namespace Opm PhaseVec mob; BOOST_STATIC_ASSERT(np == 3); for (int cell = 0; cell < num_cells; ++cell) { - FluidStateBlackoil state = fluid.computeState(phase_pressure[cell], z[cell]); + FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], z[cell]); totcompr[cell] = state.total_compressibility_; totphasevol[cell] = state.total_phase_volume_; saturation[cell] = state.saturation_; @@ -141,7 +141,7 @@ namespace Opm int num = 0; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { - phase_p[j] = phase_pressure[c[j]]; + phase_p[j] = cell_pressure[c[j]]; z_face += z[c[j]]; ++num; } else { @@ -164,7 +164,7 @@ namespace Opm phasemobf[np*face + phase] = phasemobc[c[upwind]][phase]; } } - FluidStateBlackoil face_state = fluid.computeState(phase_pressure_face[face], z_face); + FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], z_face); std::copy(face_state.phase_to_comp_, face_state.phase_to_comp_ + nc*np, &faceA[face*nc*np]); } From b8d5e6c845209a7527cf033096b2e35dbc073207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 6 Dec 2010 16:58:04 +0100 Subject: [PATCH 029/113] Now computes faceA in the same way as is done in Matlab, I think. --- dune/porsol/blackoil/BlackoilFluid.hpp | 47 ++++++++++++++++---------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 53981767..e001c231 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -93,10 +93,10 @@ namespace Opm const BlackoilFluid& fluid, const std::vector& cell_pressure, const std::vector& face_pressure, - const std::vector& z, + const std::vector& cell_z, const CompVec& bdy_z) { - int num_cells = z.size(); + int num_cells = cell_z.size(); ASSERT(num_cells == grid.numCells()); int num_faces = face_pressure.size(); ASSERT(num_faces == grid.numFaces()); @@ -113,10 +113,9 @@ namespace Opm faceA.resize(num_faces*nc*np); phasemobf.resize(np*num_faces); phasemobc.resize(num_cells); - PhaseVec mob; BOOST_STATIC_ASSERT(np == 3); for (int cell = 0; cell < num_cells; ++cell) { - FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], z[cell]); + FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], cell_z[cell]); totcompr[cell] = state.total_compressibility_; totphasevol[cell] = state.total_phase_volume_; saturation[cell] = state.saturation_; @@ -132,39 +131,53 @@ namespace Opm frac_flow[cell] = state.mobility_; frac_flow[cell] /= total_mobility; } + // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. // Set faceA by using average of cells' z and face pressures. for (int face = 0; face < num_faces; ++face) { int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; PhaseVec phase_p[2]; - CompVec z_face(0.0); - int num = 0; + PhaseVec phase_mob[2]; + CompVec face_z(0.0); + bool bdy = false; + bool inflow_bdy = false; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { phase_p[j] = cell_pressure[c[j]]; - z_face += z[c[j]]; - ++num; + phase_mob[j] = phasemobc[c[j]]; + face_z += cell_z[c[j]]; } else { - // Boundaries get essentially -inf pressure for upwinding purpose. \TODO handle BCs. - phase_p[j] = PhaseVec(-1e100); - // \TODO The two lines below are wrong for outflow faces. - z_face += bdy_z; - ++num; + bdy = true; + phase_p[j] = face_pressure[face]; + /// \TODO with capillary pressures etc., what is an inflow bdy. + /// Using Liquid phase pressure here. + inflow_bdy = face_pressure[face][Liquid] + > cell_pressure[c[(j+1)%2]][Liquid]; + if (inflow_bdy) { + FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); + phase_mob[j] = bdy_state.mobility_; + face_z += bdy_z; + } else { + phase_p[j] = -1e100; // To ensure correct upwinding. + // No need to set phase_mob[j]. + } } } - z_face /= double(num); + if (!bdy || inflow_bdy) { + face_z *= 0.5; + } for (int phase = 0; phase < np; ++phase) { if (phase_p[0][phase] == phase_p[1][phase]) { // Average mobilities. - double aver = 0.5*(phasemobc[c[0]][phase] + phasemobc[c[1]][phase]); + double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); phasemobf[np*face + phase] = aver; } else { // Upwind mobilities. int upwind = (phase_p[0][phase] > phase_p[1][phase]) ? 0 : 1; - phasemobf[np*face + phase] = phasemobc[c[upwind]][phase]; + phasemobf[np*face + phase] = phase_mob[upwind][phase]; } } - FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], z_face); + FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); std::copy(face_state.phase_to_comp_, face_state.phase_to_comp_ + nc*np, &faceA[face*nc*np]); } From fac350b657f23a2aab9869b34905bc01d4651414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 7 Dec 2010 11:37:07 +0100 Subject: [PATCH 030/113] Volume disrcrepancy is now computed with other fluid data. --- dune/porsol/blackoil/BlackoilFluid.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index e001c231..13ec3055 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -76,6 +76,8 @@ namespace Opm // Per-cell data. std::vector totcompr; // Total compressibility. std::vector totphasevol; // Total volume filled by fluid phases. + std::vector voldiscr; // Volume discrepancy = (totphasevol - porevol)/dt + std::vector relvoldiscr; // Relative volume discrepancy = (totphasevol - porevol)/porevol std::vector cellA; // A = RB^{-1}. Fortran ordering, flat storage. std::vector saturation; // Saturation. std::vector frac_flow; // Fractional flow. @@ -88,13 +90,15 @@ namespace Opm std::vector phasemobc; // Just a helper. Mobilities per cell. public: - template + template void compute(const Grid& grid, + const Rock& rock, const BlackoilFluid& fluid, const std::vector& cell_pressure, const std::vector& face_pressure, const std::vector& cell_z, - const CompVec& bdy_z) + const CompVec& bdy_z, + const double dt) { int num_cells = cell_z.size(); ASSERT(num_cells == grid.numCells()); @@ -105,6 +109,8 @@ namespace Opm BOOST_STATIC_ASSERT(np == nc); totcompr.resize(num_cells); totphasevol.resize(num_cells); + voldiscr.resize(num_cells); + relvoldiscr.resize(num_cells); saturation.resize(num_cells); frac_flow.resize(num_cells); rel_perm.resize(num_cells); @@ -118,6 +124,9 @@ namespace Opm FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], cell_z[cell]); totcompr[cell] = state.total_compressibility_; totphasevol[cell] = state.total_phase_volume_; + double pv = rock.porosity(cell)*grid.cellVolume(cell); + voldiscr[cell] = (totphasevol[cell] - pv)/dt; + relvoldiscr[cell] = (totphasevol[cell] - pv)/pv; saturation[cell] = state.saturation_; rel_perm[cell] = state.relperm_; viscosity[cell] = state.viscosity_; From faa27006162a826ad6b4d874d995d514c6b439a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 7 Dec 2010 16:45:49 +0100 Subject: [PATCH 031/113] Using uniform monotone approach on dead oil/gas. Changes results (improvement). --- .../porsol/blackoil/fluid/MiscibilityDead.cpp | 42 ++++++++----------- .../porsol/blackoil/fluid/MiscibilityDead.hpp | 4 +- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index e1e98645..45733570 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -33,6 +33,7 @@ #include #include #include +#include using namespace std; using namespace Dune; @@ -46,24 +47,27 @@ namespace Opm /// Constructor MiscibilityDead::MiscibilityDead(const table_t& pvd_table, const Dune::EclipseUnits& units) - : pvdx_(pvd_table) { const int region_number = 0; if (pvd_table.size() != 1) { THROW("More than one PVT-region"); } - // Convert units - const int sz = pvdx_[region_number][0].size(); - using namespace Dune::unit; - for (int i=0; i press(sz); + std::vector B_inv(sz); + std::vector visc(sz); + using namespace Dune::unit; + const double bunit = units.liqvol_r/units.liqvol_s; + for (int i = 0; i < sz; ++i) { + press[i] = convert::from(pvd_table[region_number][0][i], units.pressure); + B_inv[i] = 1.0 / convert::from(pvd_table[region_number][1][i], bunit); + visc[i] = convert::from(pvd_table[region_number][2][i], units.viscosity); } + int samples = 200; + buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); + buildUniformMonotoneTable(press, visc, samples, viscosity_); } // Destructor @@ -73,19 +77,14 @@ namespace Opm double MiscibilityDead::getViscosity(int region, double press, const surfvol_t& /*surfvol*/) const { - return linearInterpolationExtrap(pvdx_[region][0], - pvdx_[region][2], press); + return viscosity_(press); } double MiscibilityDead::B(int region, double press, const surfvol_t& /*surfvol*/) const { // Interpolate 1/B - return 1.0/linearInterpolationExtrap(pvdx_[region][0], - pvdx_[region][1], press); - - //return linearInterpolationExtrap(pvdx_[region][0], - //pvdx_[region_number_][1], press); + return 1.0/one_over_B_(press); } double MiscibilityDead::dBdp(int region, double press, const surfvol_t& /*surfvol*/) const @@ -93,12 +92,7 @@ namespace Opm // Interpolate 1/B surfvol_t dummy_surfvol; double Bg = B(region, press, dummy_surfvol); - return -Bg*Bg* - linearInterpolDerivative(pvdx_[region][0], - pvdx_[region][1], press); - - //return linearInterpolDerivative(pvdx_[region][0], - // pvdx_[region][1], press); + return -Bg*Bg*one_over_B_.derivative(press); } double MiscibilityDead::R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp index 2cc40e07..517df19e 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp @@ -36,6 +36,7 @@ */ #include "MiscibilityProps.hpp" +#include #include @@ -58,7 +59,8 @@ namespace Opm private: // PVT properties of dry gas or dead oil - table_t pvdx_; + Dune::utils::UniformTableLinear one_over_B_; + Dune::utils::UniformTableLinear viscosity_; }; } From 1f6f70c39d72fb86bce3e124f627c4af54814612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 8 Dec 2010 11:15:11 +0100 Subject: [PATCH 032/113] Larger number of samples, power-of-two intervals. --- dune/porsol/blackoil/fluid/MiscibilityDead.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 45733570..6cb5bae2 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -65,7 +65,7 @@ namespace Opm B_inv[i] = 1.0 / convert::from(pvd_table[region_number][1][i], bunit); visc[i] = convert::from(pvd_table[region_number][2][i], units.viscosity); } - int samples = 200; + int samples = 1025; buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); buildUniformMonotoneTable(press, visc, samples, viscosity_); } From 30a7644e9f551a0627dcb8150448bfda8c3f55c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 6 Jan 2011 10:12:02 +0100 Subject: [PATCH 033/113] Update for sub-repo state change. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 593080b7..07a7673b 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -266,7 +266,7 @@ public: { throw std::logic_error("diffCoeff() not implemented."); return 0.0; - }; + } /*! * \brief Given a phase's composition, temperature and pressure, From 4752cecffadc5441046261d1b7e235f75229e969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 11 Jan 2011 16:11:50 +0100 Subject: [PATCH 034/113] Added surfaceDensities(). --- dune/porsol/blackoil/BlackoilFluid.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 13ec3055..f78fb1b3 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -49,6 +50,11 @@ namespace Opm { fmi_params_.init(parser); FluidSystemBlackoil<>::init(parser); + const double density_unit = parser.units().density; + const std::vector& dens = parser.getDENSITY().densities_[0]; + surface_densities_[Oil] = Dune::unit::convert::from(dens[0], density_unit); + surface_densities_[Water] = Dune::unit::convert::from(dens[1], density_unit); + surface_densities_[Gas] = Dune::unit::convert::from(dens[2], density_unit); } FluidState computeState(PhaseVec phase_pressure, CompVec z) const { @@ -63,8 +69,13 @@ namespace Opm } return state; } + const CompVec& surfaceDensities() const + { + return surface_densities_; + } private: FluidMatrixInteractionBlackoilParams fmi_params_; + CompVec surface_densities_; }; From c9e9b07c5f7e9ac736882bbf9d8726d639ba4eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 13 Jan 2011 09:21:17 +0100 Subject: [PATCH 035/113] Made phasemobc public since it is needed by the transport solver. --- dune/porsol/blackoil/BlackoilFluid.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index f78fb1b3..9771e278 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -97,8 +97,7 @@ namespace Opm // Per-face data. std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). - private: - std::vector phasemobc; // Just a helper. Mobilities per cell. + std::vector phasemobc; // Phase mobilities per cell. public: template From f7dc641f4fe7b4e9b3b7ccf9d5b2c0288a0672cc Mon Sep 17 00:00:00 2001 From: Ove Saevareid Date: Fri, 14 Jan 2011 17:15:04 +0100 Subject: [PATCH 036/113] Bugfix --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 07a7673b..05a4be5e 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -175,7 +175,7 @@ public: double detR = 1.0 - R[Vapour]*R[Liquid]; u[Aqua] = B[Aqua]*z[Water]; u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; - u[Liquid] = B[Aqua]*(z[Oil] - R[Vapour]*z[Gas])/detR; + u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; fluid_state.total_phase_volume_ = u[Aqua] + u[Vapour] + u[Liquid]; // Update saturations. From 419faa324fb8915f5c05c5de22a19d8b826f60a2 Mon Sep 17 00:00:00 2001 From: Ove Saevareid Date: Tue, 18 Jan 2011 14:33:55 +0100 Subject: [PATCH 037/113] BugReport: MiscibilityLiveOil::miscible_oil, several issues here ... --- dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index f88f2c94..bfeebfa9 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -179,21 +179,23 @@ namespace Opm saturated_oil_table_[item], press); } else { // Undersaturated case + std::cerr << "###\n### MiscibilityLiveOil::miscible_oil, undersaturated case, cannot be trusted ...\n###" << std::endl; + exit(-1); int is = tableIndex(saturated_oil_table_[3], maxR); // Extrapolate from first table section if (is == 0 && press < saturated_oil_table_[0][0]) { - return linearInterpolationExtrap(undersat_oil_tables_[0][0], + return linearInterpolationExtrap(undersat_oil_tables_[0][0], // pressure ... // Dimensions? undersat_oil_tables_[0][item], - maxR); + maxR); // NOT pressure ... } // Extrapolate from last table section int ltp = saturated_oil_table_[0].size() - 1; if (is+1 == ltp && press > saturated_oil_table_[0][ltp]) { - return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], + return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], // pressure ... // Dimension ok -> eclipse PVTO undersat_oil_tables_[ltp][item], - maxR); + maxR); // NOT pressure ... } // Interpolate between table sections @@ -211,7 +213,7 @@ namespace Opm undersat_oil_tables_[is][item], press); double val2 = - linearInterpolationExtrap(undersat_oil_tables_[is+1][0], + linearInterpolationExtrap(undersat_oil_tables_[is+1][0], // Dimensions? undersat_oil_tables_[is+1][item], press); double val = val1 + w*(val2 - val1); From 5c358c2de4f2d45d553258b60f080d76f289f29e Mon Sep 17 00:00:00 2001 From: Ove Saevareid Date: Tue, 25 Jan 2011 11:52:50 +0100 Subject: [PATCH 038/113] MiscibilityLiveOil: Additional undersaturated table entries and a few fixes. --- .../blackoil/fluid/MiscibilityLiveOil.cpp | 104 ++++++++++++++++-- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index bfeebfa9..8595fa94 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -81,6 +81,92 @@ namespace Opm undersat_oil_tables_[i][2][j] = convert::from(pvto[region_number][i][++k], units.viscosity); // mu_o } } + + + // Fill in additional entries in undersaturated tables by interpolating/extrapolating 1/Bo and mu_o ... + int iPrev = -1; + int iNext = 1; + while (undersat_oil_tables_[iNext][0].size() < 2) { + ++iNext; + } + assert(iNext < sz); + for (int i=0; i 1) { + iPrev = i; + continue; + } + + bool flagPrev = (iPrev >= 0); + bool flagNext = true; + if (iNext < i) { + iPrev = iNext; + flagPrev = true; + iNext = i+1; + while (undersat_oil_tables_[iNext][0].size() < 2) { + ++iNext; + } + } + double slopePrevBinv = 0.0; + double slopePrevVisc = 0.0; + double slopeNextBinv = 0.0; + double slopeNextVisc = 0.0; + while (flagPrev || flagNext) { + double pressure0 = undersat_oil_tables_[i][0].back(); + double pressure = 1.0e47; + if (flagPrev) { + std::vector::iterator itPrev = upper_bound(undersat_oil_tables_[iPrev][0].begin(), + undersat_oil_tables_[iPrev][0].end(),pressure0+1.); + if (itPrev == undersat_oil_tables_[iPrev][0].end()) { + --itPrev; // Extrapolation ... + } else if (itPrev == undersat_oil_tables_[iPrev][0].begin()) { + ++itPrev; + } + if (itPrev == undersat_oil_tables_[iPrev][0].end()-1) { + flagPrev = false; // Last data set for "prev" ... + } + double dPPrev = *itPrev - *(itPrev-1); + pressure = *itPrev; + int index = int(itPrev - undersat_oil_tables_[iPrev][0].begin()); + slopePrevBinv = (undersat_oil_tables_[iPrev][1][index] - undersat_oil_tables_[iPrev][1][index-1])/dPPrev; + slopePrevVisc = (undersat_oil_tables_[iPrev][2][index] - undersat_oil_tables_[iPrev][2][index-1])/dPPrev; + } + if (flagNext) { + std::vector::iterator itNext = upper_bound(undersat_oil_tables_[iNext][0].begin(), + undersat_oil_tables_[iNext][0].end(),pressure0+1.); + if (itNext == undersat_oil_tables_[iNext][0].end()) { + --itNext; // Extrapolation ... + } else if (itNext == undersat_oil_tables_[iNext][0].begin()) { + ++itNext; + } + if (itNext == undersat_oil_tables_[iNext][0].end()-1) { + flagNext = false; // Last data set for "next" ... + } + double dPNext = *itNext - *(itNext-1); + if (flagPrev) { + pressure = std::min(pressure,*itNext); + } else { + pressure = *itNext; + } + int index = int(itNext - undersat_oil_tables_[iNext][0].begin()); + slopeNextBinv = (undersat_oil_tables_[iNext][1][index] - undersat_oil_tables_[iNext][1][index-1])/dPNext; + slopeNextVisc = (undersat_oil_tables_[iNext][2][index] - undersat_oil_tables_[iNext][2][index-1])/dPNext; + } + double dP = pressure - pressure0; + if (iPrev >= 0) { + double w = (saturated_oil_table_[3][i] - saturated_oil_table_[3][iPrev]) / + (saturated_oil_table_[3][iNext] - saturated_oil_table_[3][iPrev]); + undersat_oil_tables_[i][0].push_back(pressure0+dP); + undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back() + + dP*(slopePrevBinv+w*(slopeNextBinv-slopePrevBinv))); + undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back() + + dP*(slopePrevVisc+w*(slopeNextVisc-slopePrevVisc))); + } else { + undersat_oil_tables_[i][0].push_back(pressure0+dP); + undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back()+dP*slopeNextBinv); + undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back()+dP*slopeNextVisc); + } + } + } } // Destructor MiscibilityLiveOil::~MiscibilityLiveOil() @@ -151,7 +237,7 @@ namespace Opm press); } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[3], maxR); - if (undersat_oil_tables_[is][0].size() < 2) { + if (undersat_oil_tables_[is][0].size() < 2) { // Not anymore ... double val = (saturated_oil_table_[item][is+1] - saturated_oil_table_[item][is]) / (saturated_oil_table_[0][is+1] - @@ -179,30 +265,28 @@ namespace Opm saturated_oil_table_[item], press); } else { // Undersaturated case - std::cerr << "###\n### MiscibilityLiveOil::miscible_oil, undersaturated case, cannot be trusted ...\n###" << std::endl; - exit(-1); - int is = tableIndex(saturated_oil_table_[3], maxR); + int is = tableIndex(saturated_oil_table_[3], maxR); // Extrapolate from first table section if (is == 0 && press < saturated_oil_table_[0][0]) { - return linearInterpolationExtrap(undersat_oil_tables_[0][0], // pressure ... // Dimensions? + return linearInterpolationExtrap(undersat_oil_tables_[0][0], undersat_oil_tables_[0][item], - maxR); // NOT pressure ... + press); } // Extrapolate from last table section int ltp = saturated_oil_table_[0].size() - 1; if (is+1 == ltp && press > saturated_oil_table_[0][ltp]) { - return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], // pressure ... // Dimension ok -> eclipse PVTO + return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], undersat_oil_tables_[ltp][item], - maxR); // NOT pressure ... + press); } // Interpolate between table sections double w = (maxR - saturated_oil_table_[3][is]) / (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); - if (undersat_oil_tables_[is][0].size() < 2) { + if (undersat_oil_tables_[is][0].size() < 2) { // Not anymore ... double val = saturated_oil_table_[item][is] + w*(saturated_oil_table_[item][is+1] - saturated_oil_table_[item][is]); @@ -213,7 +297,7 @@ namespace Opm undersat_oil_tables_[is][item], press); double val2 = - linearInterpolationExtrap(undersat_oil_tables_[is+1][0], // Dimensions? + linearInterpolationExtrap(undersat_oil_tables_[is+1][0], undersat_oil_tables_[is+1][item], press); double val = val1 + w*(val2 - val1); From 1e27b84dd8feab70d3ce0d89bf98bfc55a8b3b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 26 Jan 2011 16:01:04 +0100 Subject: [PATCH 039/113] Changed order of phases and components. --- dune/porsol/blackoil/fluid/BlackoilDefs.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp index c0cfe15b..091e92b9 100644 --- a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp @@ -33,8 +33,8 @@ namespace Opm enum { numComponents = 3 }; enum { numPhases = 3 }; - enum ComponentIndex { Water = 0, Gas = 1, Oil = 2 }; - enum PhaseIndex { Aqua = 0, Vapour = 1, Liquid = 2 }; + enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 }; + enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; typedef double Scalar; typedef Dune::FieldVector CompVec; From 6f9ef5a32cd5f46be5ac65dab5cc39b4257ae544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 1 Feb 2011 12:40:05 +0100 Subject: [PATCH 040/113] Added output operator for easy dumping of tables. --- dune/porsol/common/UniformTableLinear.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dune/porsol/common/UniformTableLinear.hpp b/dune/porsol/common/UniformTableLinear.hpp index 644ad762..cf3bef25 100644 --- a/dune/porsol/common/UniformTableLinear.hpp +++ b/dune/porsol/common/UniformTableLinear.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,8 @@ namespace Dune { std::vector y_values_; RangePolicy left_; RangePolicy right_; + template + friend std::ostream& operator<<(std::ostream& os, const UniformTableLinear& t); }; @@ -238,6 +241,19 @@ namespace Dune { right_ = rp; } + + template + inline std::ostream& operator<<(std::ostream& os, const UniformTableLinear& t) + { + int n = t.y_values_.size(); + for (int i = 0; i < n; ++i) { + double f = double(i)/double(n - 1); + os << (1.0 - f)*t.xmin_ + f*t.xmax_ + << " " << t.y_values_[i] << '\n'; + } + return os; + } + } // namespace utils } // namespace Dune From 4f78892dc4bd67fbf94360ae4edc6f59ba8dbceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 1 Feb 2011 12:40:32 +0100 Subject: [PATCH 041/113] Added (commented out) code to dump tables. --- dune/porsol/blackoil/fluid/MiscibilityDead.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 6cb5bae2..b22d18d0 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -34,6 +34,9 @@ #include #include #include +#include +#include +#include using namespace std; using namespace Dune; @@ -68,6 +71,13 @@ namespace Opm int samples = 1025; buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); buildUniformMonotoneTable(press, visc, samples, viscosity_); + + // Dumping the created tables. +// static int count = 0; +// std::ofstream os((std::string("dump-") + boost::lexical_cast(count++)).c_str()); +// os.precision(15); +// os << "1/B\n\n" << one_over_B_ +// << "\n\nvisc\n\n" << viscosity_ << std::endl; } // Destructor From c6835bb9a7d7697ac0e351b855b662d9149503c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 2 Feb 2011 10:12:12 +0100 Subject: [PATCH 042/113] Now the relative volume discrepancy takes std::fabs(), so max_element() will be ok. --- dune/porsol/blackoil/BlackoilFluid.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 9771e278..c1569f09 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -136,7 +136,7 @@ namespace Opm totphasevol[cell] = state.total_phase_volume_; double pv = rock.porosity(cell)*grid.cellVolume(cell); voldiscr[cell] = (totphasevol[cell] - pv)/dt; - relvoldiscr[cell] = (totphasevol[cell] - pv)/pv; + relvoldiscr[cell] = std::fabs(totphasevol[cell] - pv)/pv; saturation[cell] = state.saturation_; rel_perm[cell] = state.relperm_; viscosity[cell] = state.viscosity_; From 4c10c3896531cf63d057cfe4ecd9b54bf0ebfc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Thu, 3 Feb 2011 15:40:41 +0100 Subject: [PATCH 043/113] No longer converts units. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 19 ++++++++--------- .../fluid/FluidMatrixInteractionBlackoil.hpp | 17 ++------------- .../porsol/blackoil/fluid/MiscibilityDead.cpp | 13 +++++------- .../porsol/blackoil/fluid/MiscibilityDead.hpp | 4 +--- .../blackoil/fluid/MiscibilityLiveGas.cpp | 21 ++++++++----------- .../blackoil/fluid/MiscibilityLiveGas.hpp | 3 +-- .../blackoil/fluid/MiscibilityLiveOil.cpp | 20 +++++++----------- .../blackoil/fluid/MiscibilityLiveOil.hpp | 3 +-- .../blackoil/fluid/MiscibilityWater.hpp | 13 +++++------- 9 files changed, 41 insertions(+), 72 deletions(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index 7ae03c6d..a40151ec 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -20,6 +20,7 @@ #include "BlackoilPVT.hpp" #include +#include #include "MiscibilityDead.hpp" #include "MiscibilityLiveOil.hpp" #include "MiscibilityLiveGas.hpp" @@ -43,36 +44,34 @@ namespace Opm const int region_number = 0; enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; const std::vector& d = parser.getDENSITY().densities_[region_number]; - const double du = parser.units().density; - using namespace Dune::unit; - densities_[Aqua] = convert::from(d[ECL_water], du); - densities_[Vapour] = convert::from(d[ECL_gas], du); - densities_[Liquid] = convert::from(d[ECL_oil], du); + densities_[Aqua] = d[ECL_water]; + densities_[Vapour] = d[ECL_gas]; + densities_[Liquid] = d[ECL_oil]; } else { THROW("Input is missing DENSITY\n"); } // Water PVT if (parser.hasField("PVTW")) { - water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_, parser.units())); + water_props_.reset(new MiscibilityWater(parser.getPVTW().pvtw_)); } else { water_props_.reset(new MiscibilityWater(0.5*Dune::prefix::centi*Dune::unit::Poise)); // Eclipse 100 default } // Oil PVT if (parser.hasField("PVDO")) { - oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_, parser.units())); + oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_)); } else if (parser.hasField("PVTO")) { - oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_, parser.units())); + oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_)); } else { THROW("Input is missing PVDO and PVTO\n"); } // Gas PVT if (parser.hasField("PVDG")) { - gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_, parser.units())); + gas_props_.reset(new MiscibilityDead(parser.getPVDG().pvdg_)); } else if (parser.hasField("PVTG")) { - gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_, parser.units())); + gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_)); } else { THROW("Input is missing PVDG and PVTG\n"); } diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp index c998058a..dee0c3b4 100644 --- a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -21,7 +21,6 @@ #define OPM_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED #include -#include #include #include #include "BlackoilDefs.hpp" @@ -52,11 +51,11 @@ public: const std::vector& sw = swof_table[0][0]; const std::vector& krw = swof_table[0][1]; const std::vector& krow = swof_table[0][2]; - const std::vector& pcow_raw = swof_table[0][3]; + const std::vector& pcow = swof_table[0][3]; const std::vector& sg = sgof_table[0][0]; const std::vector& krg = sgof_table[0][1]; const std::vector& krog = sgof_table[0][2]; - const std::vector& pcog_raw = sgof_table[0][3]; + const std::vector& pcog = sgof_table[0][3]; // Create tables for krw, krow, krg and krog. int samples = 200; @@ -67,18 +66,6 @@ public: krocw_ = krow[0]; // At connate water -> ecl. SWOF // Create tables for pcow and pcog. - // We must convert the pressures depending on units. - double pressure_unit = ep.units().pressure; - int numw = sw.size(); - std::vector pcow(numw); - for (int i = 0; i < numw; ++i) { - pcow[i] = Dune::unit::convert::from(pcow_raw[i], pressure_unit); - } - int numg = sg.size(); - std::vector pcog(numg); - for (int i = 0; i < numg; ++i) { - pcog[i] = Dune::unit::convert::from(pcog_raw[i], pressure_unit); - } buildUniformMonotoneTable(sw, pcow, samples, pcow_); buildUniformMonotoneTable(sg, pcog, samples, pcog_); } diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index b22d18d0..4eaf447a 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -32,7 +32,6 @@ #include "MiscibilityDead.hpp" #include #include -#include #include #include #include @@ -49,24 +48,22 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityDead::MiscibilityDead(const table_t& pvd_table, const Dune::EclipseUnits& units) + MiscibilityDead::MiscibilityDead(const table_t& pvd_table) { const int region_number = 0; if (pvd_table.size() != 1) { THROW("More than one PVT-region"); } - // Convert units + // Copy data const int sz = pvd_table[region_number][0].size(); std::vector press(sz); std::vector B_inv(sz); std::vector visc(sz); - using namespace Dune::unit; - const double bunit = units.liqvol_r/units.liqvol_s; for (int i = 0; i < sz; ++i) { - press[i] = convert::from(pvd_table[region_number][0][i], units.pressure); - B_inv[i] = 1.0 / convert::from(pvd_table[region_number][1][i], bunit); - visc[i] = convert::from(pvd_table[region_number][2][i], units.viscosity); + press[i] = pvd_table[region_number][0][i]; + B_inv[i] = 1.0 / pvd_table[region_number][1][i]; + visc[i] = pvd_table[region_number][2][i]; } int samples = 1025; buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp index 517df19e..1d9d764b 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp @@ -37,8 +37,6 @@ #include "MiscibilityProps.hpp" #include -#include - namespace Opm { @@ -47,7 +45,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityDead(const table_t& pvd_table, const Dune::EclipseUnits& units); + MiscibilityDead(const table_t& pvd_table); virtual ~MiscibilityDead(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp index d2806bb8..51293fb4 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -33,7 +33,6 @@ #include "MiscibilityLiveGas.hpp" #include #include -#include using namespace std; using namespace Dune; @@ -46,7 +45,7 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg, const EclipseUnits& units) + MiscibilityLiveGas::MiscibilityLiveGas(const table_t& pvtg) { // GAS, PVTG const int region_number = 0; @@ -58,14 +57,12 @@ namespace Opm for (int k=0; k<4; ++k) { saturated_gas_table_[k].resize(sz); } - using namespace Dune::unit; - const double bunit = units.gasvol_r/units.gasvol_s; - const double runit = units.liqvol_s/units.gasvol_s; + for (int i=0; i namespace Opm { @@ -45,7 +44,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityLiveGas(const table_t& pvto, const Dune::EclipseUnits& units); + MiscibilityLiveGas(const table_t& pvto); virtual ~MiscibilityLiveGas(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 8595fa94..cc97f91b 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -32,7 +32,6 @@ #include "MiscibilityLiveOil.hpp" #include #include -#include using namespace std; using namespace Dune; @@ -46,7 +45,7 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto, const EclipseUnits& units) + MiscibilityLiveOil::MiscibilityLiveOil(const table_t& pvto) { // OIL, PVTO const int region_number = 0; @@ -58,14 +57,11 @@ namespace Opm for (int k=0; k<4; ++k) { saturated_oil_table_[k].resize(sz); } - using namespace Dune::unit; - const double bunit = units.liqvol_r/units.liqvol_s; - const double runit = units.gasvol_s/units.liqvol_s; for (int i=0; i namespace Opm { @@ -45,7 +44,7 @@ namespace Opm public: typedef std::vector > > table_t; - MiscibilityLiveOil(const table_t& pvto, const Dune::EclipseUnits& units); + MiscibilityLiveOil(const table_t& pvto); virtual ~MiscibilityLiveOil(); virtual double getViscosity(int region, double press, const surfvol_t& surfvol) const; diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index 7cfb22b8..8dd60032 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -36,8 +36,6 @@ #include "MiscibilityProps.hpp" #include -#include -#include // Forward declaration. class PVTW; @@ -48,17 +46,16 @@ namespace Opm { public: typedef std::vector > table_t; - MiscibilityWater(const table_t& pvtw, const Dune::EclipseUnits& units) + MiscibilityWater(const table_t& pvtw) { const int region_number = 0; if (pvtw.size() != 1) { THROW("More than one PVD-region"); } - using namespace Dune::unit; - ref_press_ = convert::from(pvtw[region_number][0], units.pressure); - ref_B_ = convert::from(pvtw[region_number][1], units.liqvol_r/units.liqvol_s); - comp_ = convert::from(pvtw[region_number][2], units.compressibility); - viscosity_ = convert::from(pvtw[region_number][3], units.viscosity); + ref_press_ = pvtw[region_number][0]; + ref_B_ = pvtw[region_number][1]; + comp_ = pvtw[region_number][2]; + viscosity_ = pvtw[region_number][3]; if (pvtw[region_number].size() > 4 && pvtw[region_number][4] != 0.0) { THROW("MiscibilityWater does not support 'viscosibility'."); } From a27015d00ccba65e9ba124cc30c73ad47963477a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Thu, 3 Feb 2011 15:41:20 +0100 Subject: [PATCH 044/113] No longer converts units. --- dune/porsol/blackoil/BlackoilFluid.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index c1569f09..61160260 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -26,7 +26,6 @@ #include #include #include -#include #include @@ -50,11 +49,10 @@ namespace Opm { fmi_params_.init(parser); FluidSystemBlackoil<>::init(parser); - const double density_unit = parser.units().density; const std::vector& dens = parser.getDENSITY().densities_[0]; - surface_densities_[Oil] = Dune::unit::convert::from(dens[0], density_unit); - surface_densities_[Water] = Dune::unit::convert::from(dens[1], density_unit); - surface_densities_[Gas] = Dune::unit::convert::from(dens[2], density_unit); + surface_densities_[Oil] = dens[0]; + surface_densities_[Water] = dens[1]; + surface_densities_[Gas] = dens[2]; } FluidState computeState(PhaseVec phase_pressure, CompVec z) const { From 492ad8425e725b042973ada5902d7e33f909b203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Wed, 9 Feb 2011 11:28:00 +0100 Subject: [PATCH 045/113] Now handles PVCDO. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index a40151ec..88221541 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -63,6 +63,8 @@ namespace Opm oil_props_.reset(new MiscibilityDead(parser.getPVDO().pvdo_)); } else if (parser.hasField("PVTO")) { oil_props_.reset(new MiscibilityLiveOil(parser.getPVTO().pvto_)); + } else if (parser.hasField("PVCDO")) { + oil_props_.reset(new MiscibilityWater(parser.getPVCDO().pvcdo_)); } else { THROW("Input is missing PVDO and PVTO\n"); } @@ -73,7 +75,7 @@ namespace Opm } else if (parser.hasField("PVTG")) { gas_props_.reset(new MiscibilityLiveGas(parser.getPVTG().pvtg_)); } else { - THROW("Input is missing PVDG and PVTG\n"); + THROW("Input is missing PVDG and PVTG\n"); } } From c7950ff3417f9f89f89f469db038d0a1bd7f91af Mon Sep 17 00:00:00 2001 From: Ove Saevareid Date: Fri, 11 Feb 2011 11:32:52 +0100 Subject: [PATCH 046/113] Correcting (hopefully:)) compressibility computations. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 05a4be5e..87f24a8b 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -217,8 +217,11 @@ public: double data_for_C[numComponents*numPhases]; Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); Dune::prod(Ai, dA, C); - CompVec ones(1.0); - cp = Dune::prod(C, ones); + //CompVec ones(1.0); + //cp = Dune::prod(C, ones); // Probably C' and not C; we want phasewise compressibilities: + cp[Aqua] = C(Water, Aqua); + cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); + cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); fluid_state.total_compressibility_ = cp*s; } From f6c378e5783c93c983b49adb3efe8eca7fc2e7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Thu, 3 Mar 2011 09:04:47 +0100 Subject: [PATCH 047/113] OpenMP parallelization --- dune/porsol/blackoil/BlackoilFluid.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 61160260..6c12fa57 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -128,6 +128,7 @@ namespace Opm phasemobf.resize(np*num_faces); phasemobc.resize(num_cells); BOOST_STATIC_ASSERT(np == 3); +#pragma omp parallel for for (int cell = 0; cell < num_cells; ++cell) { FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], cell_z[cell]); totcompr[cell] = state.total_compressibility_; @@ -151,6 +152,7 @@ namespace Opm // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. // Set faceA by using average of cells' z and face pressures. +#pragma omp parallel for for (int face = 0; face < num_faces; ++face) { int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; PhaseVec phase_p[2]; From 1b84280ab4efcb348cb7c21385e52afa3a85ec6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 8 Mar 2011 10:13:07 +0100 Subject: [PATCH 048/113] Added program printing some fluid properties. --- .../blackoil/test/bo_fluid_pressuredeps.cpp | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp new file mode 100644 index 00000000..a5d103ea --- /dev/null +++ b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp @@ -0,0 +1,64 @@ +/* + Copyright 2010 SINTEF ICT, Applied Mathematics. + + 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 . +*/ + + +#include +#include +#include + + +int main(int argc, char** argv) +{ + // Parameters. + Dune::parameter::ParameterGroup param(argc, argv); + + // Parser. + std::string ecl_file = param.get("filename"); + Dune::EclipseGridParser parser(ecl_file); + + // Look at the BlackoilFluid behaviour + Opm::BlackoilFluid fluid; + fluid.init(parser); + Opm::BlackoilFluid::CompVec z(0.0); + z[Opm::BlackoilFluid::Water] = param.getDefault("z_w", 0.0); + z[Opm::BlackoilFluid::Oil] = param.getDefault("z_o", 1.0); + z[Opm::BlackoilFluid::Gas] = param.getDefault("z_g", 0.0); + int num_pts = param.getDefault("num_pts", 41); + double min_press = param.getDefault("min_press", 1e7); + double max_press = param.getDefault("max_press", 3e7); + for (int i = 0; i < num_pts; ++i) { + double factor = double(i)/double(num_pts - 1); + double p = (1.0 - factor)*min_press + factor*max_press; + Opm::BlackoilFluid::FluidState state = fluid.computeState(Opm::BlackoilFluid::PhaseVec(p), z); + double totmob = 0.0; + for (int phase = 0; phase < Opm::BlackoilFluid::numPhases; ++phase) { + totmob += state.mobility_[phase]; + } + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + std::cout << p << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_compressibility_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << totmob << '\n'; + } +} From 5924dc93878111ae60a48a52373705a6ff382ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 17 Mar 2011 08:28:36 +0100 Subject: [PATCH 049/113] Added computation of new term, for the experimental pressure solver jacobian. --- dune/porsol/blackoil/BlackoilFluid.hpp | 8 ++++++++ dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 1 + dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 6 +++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 6c12fa57..5f086e2d 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -92,6 +92,10 @@ namespace Opm std::vector frac_flow; // Fractional flow. std::vector rel_perm; // Relative permeability. std::vector viscosity; // Viscosity. + + // Extra data. + std::vector expjacterm; + // Per-face data. std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). @@ -123,6 +127,7 @@ namespace Opm frac_flow.resize(num_cells); rel_perm.resize(num_cells); viscosity.resize(num_cells); + expjacterm.resize(num_cells); cellA.resize(num_cells*nc*np); faceA.resize(num_faces*nc*np); phasemobf.resize(np*num_faces); @@ -148,6 +153,9 @@ namespace Opm } frac_flow[cell] = state.mobility_; frac_flow[cell] /= total_mobility; + + // Experimental + expjacterm[cell] = state.experimental_term_; } // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index f359e890..0f86f011 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -40,6 +40,7 @@ namespace Opm PhaseVec saturation_; PhaseVec phase_compressibility_; Scalar total_compressibility_; + Scalar experimental_term_; PhaseVec viscosity_; PhaseVec relperm_; PhaseVec mobility_; diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 87f24a8b..f6887673 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -221,8 +221,12 @@ public: //cp = Dune::prod(C, ones); // Probably C' and not C; we want phasewise compressibilities: cp[Aqua] = C(Water, Aqua); cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); - cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); + cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); fluid_state.total_compressibility_ = cp*s; + + // Experimental term. + PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); + fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; } /*! From ade30ebd678ad50861f757733b6e2cfd516d8605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 17 Mar 2011 08:28:57 +0100 Subject: [PATCH 050/113] Output experimental term. --- dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp index a5d103ea..4b5ace60 100644 --- a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp @@ -59,6 +59,12 @@ int main(int argc, char** argv) std::cout << state.total_compressibility_ << " "; std::cout.width(15); std::cout.fill(' '); - std::cout << totmob << '\n'; + std::cout << totmob << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_phase_volume_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.experimental_term_ << '\n'; } } From f3a2d5fff6811f04e54abc59561ed30f3332fbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 8 Apr 2011 11:11:46 +0200 Subject: [PATCH 051/113] Added saturation printing option. --- .../blackoil/test/bo_fluid_pressuredeps.cpp | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp index 4b5ace60..ddd66017 100644 --- a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp @@ -42,6 +42,7 @@ int main(int argc, char** argv) int num_pts = param.getDefault("num_pts", 41); double min_press = param.getDefault("min_press", 1e7); double max_press = param.getDefault("max_press", 3e7); + bool print_compr = param.getDefault("print_compr", true); for (int i = 0; i < num_pts; ++i) { double factor = double(i)/double(num_pts - 1); double p = (1.0 - factor)*min_press + factor*max_press; @@ -50,21 +51,40 @@ int main(int argc, char** argv) for (int phase = 0; phase < Opm::BlackoilFluid::numPhases; ++phase) { totmob += state.mobility_[phase]; } - std::cout.precision(6); - std::cout.width(15); - std::cout.fill(' '); - std::cout << p << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.total_compressibility_ << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << totmob << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.total_phase_volume_ << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.experimental_term_ << '\n'; + if (print_compr) { + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + std::cout << p << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_compressibility_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << totmob << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_phase_volume_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.experimental_term_ << '\n'; + } else { + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + std::cout << p << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[0] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[1] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[2] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_phase_volume_ << '\n'; + } } } From 7158081b1a807ecacdd6d77643a46966d4161119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 11 Apr 2011 13:32:35 +0200 Subject: [PATCH 052/113] Added dkr() member. --- .../fluid/FluidMatrixInteractionBlackoil.hpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp index dee0c3b4..cd323f06 100644 --- a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp @@ -165,6 +165,39 @@ public: kr[Liquid] = 0.0; } } + + + /*! + * \brief The saturation derivatives of relative permeability of all phases. + */ + template + static void dkr(krContainerT &dkr, + const Params ¶ms, + const SatContainerT &saturations, + Scalar /*temperature*/) + { + for (int p1 = 0; p1 < numPhases; ++p1) { + for (int p2 = 0; p2 < numPhases; ++p2) { + dkr[p1][p2] = 0.0; + } + } + // Stone-II relative permeability model. + Scalar sw = saturations[Aqua]; + Scalar sg = saturations[Vapour]; + Scalar krw = params.krw_(sw); + Scalar dkrww = params.krw_.derivative(sw); + Scalar krg = params.krg_(sg); + Scalar dkrgg = params.krg_.derivative(sg); + Scalar krow = params.krow_(sw); + Scalar dkrow = params.krow_.derivative(sw); + Scalar krog = params.krog_(sg); + Scalar dkrog = params.krog_.derivative(sg); + Scalar krocw = params.krocw_; + dkr[Aqua][Aqua] = dkrww; + dkr[Vapour][Vapour] = dkrgg; + dkr[Liquid][Aqua] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); + dkr[Liquid][Vapour] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg); + } }; } // namespace Opm From a0f82cbe3916ab96915eee86f57ce0a676ac3709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 11 Apr 2011 13:33:32 +0200 Subject: [PATCH 053/113] Added drelperm_ and dmobility_ to store derivatives. --- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 0f86f011..7da95b2a 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -43,7 +43,9 @@ namespace Opm Scalar experimental_term_; PhaseVec viscosity_; PhaseVec relperm_; + Dune::FieldVector, numPhases> drelperm_; PhaseVec mobility_; + Dune::FieldVector, numPhases> dmobility_; }; } // end namespace Opm From 93e0cda4cdb75ed3565e226f852a0b4f5a39be1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 11 Apr 2011 13:34:27 +0200 Subject: [PATCH 054/113] Added support for upwind computation of mobility derivatives. --- dune/porsol/blackoil/BlackoilFluid.hpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 5f086e2d..0061abb7 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -62,8 +62,12 @@ namespace Opm state.surface_volume_ = z; FluidSystemBlackoil<>::computeEquilibrium(state); // Sets everything but relperm and mobility. FluidMatrixInteractionBlackoil::kr(state.relperm_, fmi_params_, state.saturation_, state.temperature_); + FluidMatrixInteractionBlackoil::dkr(state.drelperm_, fmi_params_, state.saturation_, state.temperature_); for (int phase = 0; phase < numPhases; ++phase) { state.mobility_[phase] = state.relperm_[phase]/state.viscosity_[phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + state.dmobility_[phase][p2] = state.drelperm_[phase][p2]/state.viscosity_[phase]; + } } return state; } @@ -97,9 +101,12 @@ namespace Opm std::vector expjacterm; // Per-face data. - std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. - std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). - std::vector phasemobc; // Phase mobilities per cell. + std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. + std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). + std::vector phasemobc; // Phase mobilities per cell. + std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). + typedef Dune::FieldVector, numPhases> PhaseMat; + std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. public: template @@ -132,6 +139,8 @@ namespace Opm faceA.resize(num_faces*nc*np); phasemobf.resize(np*num_faces); phasemobc.resize(num_cells); + phasemobf_deriv.resize(np*np*num_faces); + phasemobc_deriv.resize(np*np*num_cells); BOOST_STATIC_ASSERT(np == 3); #pragma omp parallel for for (int cell = 0; cell < num_cells; ++cell) { @@ -145,6 +154,7 @@ namespace Opm rel_perm[cell] = state.relperm_; viscosity[cell] = state.viscosity_; phasemobc[cell] = state.mobility_; + phasemobc_deriv[cell] = state.dmobility_; std::copy(state.phase_to_comp_, state.phase_to_comp_ + nc*np, &cellA[cell*nc*np]); // Fractional flow must be calculated. double total_mobility = 0.0; @@ -165,6 +175,7 @@ namespace Opm int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; PhaseVec phase_p[2]; PhaseVec phase_mob[2]; + PhaseMat phasemob_deriv[2]; CompVec face_z(0.0); bool bdy = false; bool inflow_bdy = false; @@ -172,6 +183,7 @@ namespace Opm if (c[j] >= 0) { phase_p[j] = cell_pressure[c[j]]; phase_mob[j] = phasemobc[c[j]]; + phasemob_deriv[j] = phasemobc_deriv[c[j]]; face_z += cell_z[c[j]]; } else { bdy = true; @@ -183,6 +195,7 @@ namespace Opm if (inflow_bdy) { FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); phase_mob[j] = bdy_state.mobility_; + phasemob_deriv[j] = bdy_state.dmobility_; face_z += bdy_z; } else { phase_p[j] = -1e100; // To ensure correct upwinding. @@ -198,10 +211,17 @@ namespace Opm // Average mobilities. double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); phasemobf[np*face + phase] = aver; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] + + phasemob_deriv[1][phase][p2]; + } } else { // Upwind mobilities. int upwind = (phase_p[0][phase] > phase_p[1][phase]) ? 0 : 1; phasemobf[np*face + phase] = phase_mob[upwind][phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; + } } } FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); From 78726b306b04b6feb3f4f56872f4123e72f5a70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 13 Apr 2011 16:09:17 +0200 Subject: [PATCH 055/113] Major fix: Changing the meaning of z to surfvol *density*. Some details: - changed names of some variables to match (new) reality - fixes a bug with the experimental jacobian (which already assumed this) - initialization has changed to ensure that sum(u = Az) == 1 instead of == pv. - have not yet checked that wells are handling z correctly. --- dune/porsol/blackoil/BlackoilFluid.hpp | 15 ++++++++------- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 2 +- .../porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 0061abb7..2440b251 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -88,9 +88,10 @@ namespace Opm { // Per-cell data. std::vector totcompr; // Total compressibility. - std::vector totphasevol; // Total volume filled by fluid phases. - std::vector voldiscr; // Volume discrepancy = (totphasevol - porevol)/dt - std::vector relvoldiscr; // Relative volume discrepancy = (totphasevol - porevol)/porevol + std::vector totphasevol_density; // Total volume filled by fluid phases + // per pore volume. + std::vector voldiscr; // Volume discrepancy = (totphasevol_dens - 1)*pv/dt + std::vector relvoldiscr; // Relative volume discrepancy = |totphasevol_dens - 1| std::vector cellA; // A = RB^{-1}. Fortran ordering, flat storage. std::vector saturation; // Saturation. std::vector frac_flow; // Fractional flow. @@ -127,7 +128,7 @@ namespace Opm const int nc = numComponents; BOOST_STATIC_ASSERT(np == nc); totcompr.resize(num_cells); - totphasevol.resize(num_cells); + totphasevol_density.resize(num_cells); voldiscr.resize(num_cells); relvoldiscr.resize(num_cells); saturation.resize(num_cells); @@ -146,10 +147,10 @@ namespace Opm for (int cell = 0; cell < num_cells; ++cell) { FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], cell_z[cell]); totcompr[cell] = state.total_compressibility_; - totphasevol[cell] = state.total_phase_volume_; + totphasevol_density[cell] = state.total_phase_volume_density_; double pv = rock.porosity(cell)*grid.cellVolume(cell); - voldiscr[cell] = (totphasevol[cell] - pv)/dt; - relvoldiscr[cell] = std::fabs(totphasevol[cell] - pv)/pv; + voldiscr[cell] = (totphasevol_density[cell] - 1.0)*pv/dt; + relvoldiscr[cell] = std::fabs(totphasevol_density[cell] - 1.0); saturation[cell] = state.saturation_; rel_perm[cell] = state.relperm_; viscosity[cell] = state.viscosity_; diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 7da95b2a..c9612558 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -35,7 +35,7 @@ namespace Opm CompVec surface_volume_; PhaseVec phase_pressure_; PhaseVec phase_volume_; - Scalar total_phase_volume_; + Scalar total_phase_volume_density_; Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering PhaseVec saturation_; PhaseVec phase_compressibility_; diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index f6887673..63db5a8b 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -176,10 +176,10 @@ public: u[Aqua] = B[Aqua]*z[Water]; u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; - fluid_state.total_phase_volume_ = u[Aqua] + u[Vapour] + u[Liquid]; + fluid_state.total_phase_volume_density_ = u[Aqua] + u[Vapour] + u[Liquid]; // Update saturations. - double sumu = fluid_state.total_phase_volume_; + double sumu = fluid_state.total_phase_volume_density_; PhaseVec& s = fluid_state.saturation_; for (int i = 0; i < 3; ++i) { s[i] = u[i]/sumu; From ebecb4ad41a9956af187f7c6c69b84cb81cf79ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 13 Apr 2011 16:09:17 +0200 Subject: [PATCH 056/113] Major fix: Changing the meaning of z to surfvol *density*. Some details: - changed names of some variables to match (new) reality - fixes a bug with the experimental jacobian (which already assumed this) - initialization has changed to ensure that sum(u = Az) == 1 instead of == pv. - have not yet checked that wells are handling z correctly. --- dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp index ddd66017..4669c8b9 100644 --- a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp @@ -64,7 +64,7 @@ int main(int argc, char** argv) std::cout << totmob << " "; std::cout.width(15); std::cout.fill(' '); - std::cout << state.total_phase_volume_ << " "; + std::cout << state.total_phase_volume_density_ << " "; std::cout.width(15); std::cout.fill(' '); std::cout << state.experimental_term_ << '\n'; @@ -84,7 +84,7 @@ int main(int argc, char** argv) std::cout << state.saturation_[2] << " "; std::cout.width(15); std::cout.fill(' '); - std::cout << state.total_phase_volume_ << '\n'; + std::cout << state.total_phase_volume_density_ << '\n'; } } } From 4cfd362217e2366d89e86ee80ff96b58a9406121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 13 Apr 2011 16:45:39 +0200 Subject: [PATCH 057/113] Init fixes for changed z interpretation. --- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 2 +- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index c9612558..acb84d36 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -34,7 +34,7 @@ namespace Opm Scalar temperature_; CompVec surface_volume_; PhaseVec phase_pressure_; - PhaseVec phase_volume_; + PhaseVec phase_volume_density_; Scalar total_phase_volume_density_; Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering PhaseVec saturation_; diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 63db5a8b..76c6edd6 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -171,7 +171,7 @@ public: A(Oil, Liquid) = 1.0/B[Liquid]; // Update phase volumes. This is the same as multiplying with A^{-1} - PhaseVec& u = fluid_state.phase_volume_; + PhaseVec& u = fluid_state.phase_volume_density_; double detR = 1.0 - R[Vapour]*R[Liquid]; u[Aqua] = B[Aqua]*z[Water]; u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; From 249917bea4609bf103d096bfaaacc0530ecba47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 10 May 2011 09:36:48 +0200 Subject: [PATCH 058/113] Work in progress on fluid evaluation, correcting upwind decisions. --- dune/porsol/blackoil/BlackoilFluid.hpp | 133 +++++++++++++++++++------ 1 file changed, 102 insertions(+), 31 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 2440b251..2686b97d 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -75,6 +75,19 @@ namespace Opm { return surface_densities_; } + + /// \param[in] A state matrix in fortran ordering + PhaseVec phaseDensities(const double* A) const + { + PhaseVec phase_dens(0.0); + for (int phase = 0; phase < numPhases; ++phase) { + for (int comp = 0; comp < numComponents; ++comp) { + phase_dens[phase] += A[numComponents*phase + comp]*surface_densities_[comp]; + } + } + return phase_dens; + } + private: FluidMatrixInteractionBlackoilParams fmi_params_; CompVec surface_densities_; @@ -108,12 +121,14 @@ namespace Opm std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). typedef Dune::FieldVector, numPhases> PhaseMat; std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. + std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. public: template void compute(const Grid& grid, const Rock& rock, const BlackoilFluid& fluid, + const typename Grid::Vector gravity, const std::vector& cell_pressure, const std::vector& face_pressure, const std::vector& cell_z, @@ -126,6 +141,7 @@ namespace Opm ASSERT(num_faces == grid.numFaces()); const int np = numPhases; const int nc = numComponents; + bool nonzero_gravity = gravity.two_norm() > 0.0; BOOST_STATIC_ASSERT(np == nc); totcompr.resize(num_cells); totphasevol_density.resize(num_cells); @@ -142,6 +158,7 @@ namespace Opm phasemobc.resize(num_cells); phasemobf_deriv.resize(np*np*num_faces); phasemobc_deriv.resize(np*np*num_cells); + gravcapf.resize(np*num_faces); BOOST_STATIC_ASSERT(np == 3); #pragma omp parallel for for (int cell = 0; cell < num_cells; ++cell) { @@ -169,47 +186,102 @@ namespace Opm expjacterm[cell] = state.experimental_term_; } - // Set phasemobf to average of cells' phase mobs, if pressures are equal, else use upwinding. - // Set faceA by using average of cells' z and face pressures. + // Obtain properties from both sides of the face. #pragma omp parallel for for (int face = 0; face < num_faces; ++face) { + typedef typename Grid::Vector Vec; + Vec fc = grid.faceCentroid(face); int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; + + // Get pressures and compute gravity contributions, + // to decide upwind directions. PhaseVec phase_p[2]; - PhaseVec phase_mob[2]; - PhaseMat phasemob_deriv[2]; - CompVec face_z(0.0); - bool bdy = false; - bool inflow_bdy = false; + PhaseVec gravcontrib[2]; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { + // Pressures + phase_p[j] = cell_pressure[c[j]]; + // Gravity contribution. + if (nonzero_gravity) { + Vec cc = grid.cellCentroid(c[j]); + cc -= fc; + gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; + gravcontrib[j] *= (cc*gravity); + } else { + gravcontrib[j] = 0.0; + } + } else { + // Pressures + phase_p[j] = face_pressure[face]; + // Gravity contribution. + gravcontrib[j] = 0.0; + } + } + + // Gravity contribution. + // gravcapf = rho_1*g*(z_1 - z_12) - rho_2*g*(z_2 - z_12) + // where _1 and _2 refers to two neigbour cells, z is the + // z coordinate of the centroid, and z_12 is the face centroid. + for (int phase = 0; phase < np; ++phase) { + gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + } + + // Now we can easily find the upwind direction for every phase, + // we can also tell which boundary faces are inflow bdys. + + + PhaseVec phase_mob[2]; + PhaseMat phasemob_deriv[2]; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + // Pressures, mobilities. phase_p[j] = cell_pressure[c[j]]; phase_mob[j] = phasemobc[c[j]]; phasemob_deriv[j] = phasemobc_deriv[c[j]]; - face_z += cell_z[c[j]]; - } else { - bdy = true; - phase_p[j] = face_pressure[face]; - /// \TODO with capillary pressures etc., what is an inflow bdy. - /// Using Liquid phase pressure here. - inflow_bdy = face_pressure[face][Liquid] - > cell_pressure[c[(j+1)%2]][Liquid]; - if (inflow_bdy) { - FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); - phase_mob[j] = bdy_state.mobility_; - phasemob_deriv[j] = bdy_state.dmobility_; - face_z += bdy_z; + // Gravity contribution. + if (nonzero_gravity) { + Vec cc = grid.cellCentroid(c[j]); + cc -= fc; + gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; + gravcontrib[j] *= (cc*gravity); } else { - phase_p[j] = -1e100; // To ensure correct upwinding. - // No need to set phase_mob[j]. + gravcontrib[j] = 0.0; } + } else { + // Pressures, mobilities. + phase_p[j] = face_pressure[face]; + FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); + phase_mob[j] = bdy_state.mobility_; + phasemob_deriv[j] = bdy_state.dmobility_; + // Gravity contribution. + gravcontrib[j] = 0.0; } } - if (!bdy || inflow_bdy) { - face_z *= 0.5; + + // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. + CompVec face_z(0.0); + double face_z_factor = 0.5; + double pot_l[2] = { phase_p[0][Liquid], phase_p[1][Liquid] + gravcapf[np*face + Liquid] }; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + face_z += cell_z[c[j]]; + } else if (pot_l[j] > pot_l[(j + 1)%2]) { + // Inflow boundary. + face_z += bdy_z; + } else { + // For outflow or noflow boundaries, only cell z is used. + face_z_factor = 1.0; + // Also, make sure the boundary data are not used for mobilities. + phase_p[j] = -1e100; + } } + face_z *= face_z_factor; + + // Computing upwind mobilities and derivatives for (int phase = 0; phase < np; ++phase) { - if (phase_p[0][phase] == phase_p[1][phase]) { - // Average mobilities. + double pot[2] = { phase_p[0][phase], phase_p[1][phase] + gravcapf[np*face + phase] }; + if (pot[0] == pot[1]) { + // Average. double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); phasemobf[np*face + phase] = aver; for (int p2 = 0; p2 < numPhases; ++p2) { @@ -217,24 +289,23 @@ namespace Opm + phasemob_deriv[1][phase][p2]; } } else { - // Upwind mobilities. - int upwind = (phase_p[0][phase] > phase_p[1][phase]) ? 0 : 1; + // Upwind. + int upwind = pot[0] > pot[1] ? 0 : 1; phasemobf[np*face + phase] = phase_mob[upwind][phase]; for (int p2 = 0; p2 < numPhases; ++p2) { phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; } } } + + // Find faceA. FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); std::copy(face_state.phase_to_comp_, face_state.phase_to_comp_ + nc*np, &faceA[face*nc*np]); } - } }; - - } // namespace Opm #endif // OPM_BLACKOILFLUID_HEADER_INCLUDED From 8d81c732674a2aaeb4137181612e6370c364e89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 10 May 2011 10:17:36 +0200 Subject: [PATCH 059/113] Reordered computations for refactoring. Work in progress. --- dune/porsol/blackoil/BlackoilFluid.hpp | 33 ++++++++------------------ 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 2686b97d..6dac6588 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -218,69 +218,56 @@ namespace Opm } } - // Gravity contribution. + // Gravity contribution: // gravcapf = rho_1*g*(z_1 - z_12) - rho_2*g*(z_2 - z_12) // where _1 and _2 refers to two neigbour cells, z is the // z coordinate of the centroid, and z_12 is the face centroid. + // Also compute the potentials. + PhaseVec pot[2]; for (int phase = 0; phase < np; ++phase) { gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; + pot[1][phase] = phase_p[1][phase]; } // Now we can easily find the upwind direction for every phase, // we can also tell which boundary faces are inflow bdys. - + // Get mobilities and derivatives. PhaseVec phase_mob[2]; PhaseMat phasemob_deriv[2]; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { - // Pressures, mobilities. - phase_p[j] = cell_pressure[c[j]]; phase_mob[j] = phasemobc[c[j]]; phasemob_deriv[j] = phasemobc_deriv[c[j]]; - // Gravity contribution. - if (nonzero_gravity) { - Vec cc = grid.cellCentroid(c[j]); - cc -= fc; - gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; - gravcontrib[j] *= (cc*gravity); - } else { - gravcontrib[j] = 0.0; - } } else { - // Pressures, mobilities. - phase_p[j] = face_pressure[face]; FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); phase_mob[j] = bdy_state.mobility_; phasemob_deriv[j] = bdy_state.dmobility_; - // Gravity contribution. - gravcontrib[j] = 0.0; } } // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. CompVec face_z(0.0); double face_z_factor = 0.5; - double pot_l[2] = { phase_p[0][Liquid], phase_p[1][Liquid] + gravcapf[np*face + Liquid] }; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { face_z += cell_z[c[j]]; - } else if (pot_l[j] > pot_l[(j + 1)%2]) { + } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { // Inflow boundary. face_z += bdy_z; } else { // For outflow or noflow boundaries, only cell z is used. face_z_factor = 1.0; // Also, make sure the boundary data are not used for mobilities. - phase_p[j] = -1e100; + pot[j] = -1e100; } } face_z *= face_z_factor; // Computing upwind mobilities and derivatives for (int phase = 0; phase < np; ++phase) { - double pot[2] = { phase_p[0][phase], phase_p[1][phase] + gravcapf[np*face + phase] }; - if (pot[0] == pot[1]) { + if (pot[0][phase] == pot[1][phase]) { // Average. double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); phasemobf[np*face + phase] = aver; @@ -290,7 +277,7 @@ namespace Opm } } else { // Upwind. - int upwind = pot[0] > pot[1] ? 0 : 1; + int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; phasemobf[np*face + phase] = phase_mob[upwind][phase]; for (int p2 = 0; p2 < numPhases; ++p2) { phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; From a525f0335ecd89ea7a78273df0ed4c27a55a9d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 10 May 2011 10:21:33 +0200 Subject: [PATCH 060/113] Finished refactoring BlackoilFluidData::compute(). --- dune/porsol/blackoil/BlackoilFluid.hpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 6dac6588..b88d4519 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -233,29 +233,23 @@ namespace Opm // Now we can easily find the upwind direction for every phase, // we can also tell which boundary faces are inflow bdys. + // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. // Get mobilities and derivatives. + CompVec face_z(0.0); + double face_z_factor = 0.5; PhaseVec phase_mob[2]; PhaseMat phasemob_deriv[2]; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { + face_z += cell_z[c[j]]; phase_mob[j] = phasemobc[c[j]]; phasemob_deriv[j] = phasemobc_deriv[c[j]]; - } else { - FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); - phase_mob[j] = bdy_state.mobility_; - phasemob_deriv[j] = bdy_state.dmobility_; - } - } - - // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. - CompVec face_z(0.0); - double face_z_factor = 0.5; - for (int j = 0; j < 2; ++j) { - if (c[j] >= 0) { - face_z += cell_z[c[j]]; } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { // Inflow boundary. face_z += bdy_z; + FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); + phase_mob[j] = bdy_state.mobility_; + phasemob_deriv[j] = bdy_state.dmobility_; } else { // For outflow or noflow boundaries, only cell z is used. face_z_factor = 1.0; From c46698ff9bcaeb213697f396e7fd288d29638dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 10 May 2011 11:18:17 +0200 Subject: [PATCH 061/113] Fixing signs of gravity parts. --- dune/porsol/blackoil/BlackoilFluid.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index b88d4519..d6845e9e 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -203,10 +203,10 @@ namespace Opm phase_p[j] = cell_pressure[c[j]]; // Gravity contribution. if (nonzero_gravity) { - Vec cc = grid.cellCentroid(c[j]); - cc -= fc; + Vec cdiff = fc; + cdiff -= grid.cellCentroid(c[j]); gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; - gravcontrib[j] *= (cc*gravity); + gravcontrib[j] *= (cdiff*gravity); } else { gravcontrib[j] = 0.0; } @@ -219,15 +219,15 @@ namespace Opm } // Gravity contribution: - // gravcapf = rho_1*g*(z_1 - z_12) - rho_2*g*(z_2 - z_12) + // gravcapf = rho_1*g*(z_12 - z_1) - rho_2*g*(z_12 - z_2) // where _1 and _2 refers to two neigbour cells, z is the // z coordinate of the centroid, and z_12 is the face centroid. // Also compute the potentials. PhaseVec pot[2]; for (int phase = 0; phase < np; ++phase) { gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; - pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; - pot[1][phase] = phase_p[1][phase]; + pot[0][phase] = phase_p[0][phase]; + pot[1][phase] = phase_p[1][phase] + gravcapf[np*face + phase]; } // Now we can easily find the upwind direction for every phase, From df5df18a82765d9c20ed3bbf7da1ffad1f3737a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 10 May 2011 13:41:37 +0200 Subject: [PATCH 062/113] Fixes upwind direction with gravity influence in pressure solver. --- dune/porsol/blackoil/BlackoilFluid.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index d6845e9e..da04b4b7 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -226,8 +226,8 @@ namespace Opm PhaseVec pot[2]; for (int phase = 0; phase < np; ++phase) { gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; - pot[0][phase] = phase_p[0][phase]; - pot[1][phase] = phase_p[1][phase] + gravcapf[np*face + phase]; + pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; + pot[1][phase] = phase_p[1][phase]; } // Now we can easily find the upwind direction for every phase, From 22b54326e12315288d2099f38d24a69e07ad364f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 9 Jun 2011 09:21:48 +0200 Subject: [PATCH 063/113] Removed #include "config.h" from headers, added to sources where missing. --- dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp | 1 + dune/porsol/blackoil/test/bo_fluid_test.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp index 4669c8b9..1c6d1a44 100644 --- a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp @@ -17,6 +17,7 @@ along with OPM. If not, see . */ +#include "config.h" #include #include diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/dune/porsol/blackoil/test/bo_fluid_test.cpp index 75af0ad5..5d3d5ea4 100644 --- a/dune/porsol/blackoil/test/bo_fluid_test.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_test.cpp @@ -17,6 +17,7 @@ along with OPM. If not, see . */ +#include "config.h" #include #include From bdb52341baeaaa825393c1542d89436afd6b079e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 12:59:19 +0200 Subject: [PATCH 064/113] Added B and R factors to the state data (for easier debugging). --- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 2 ++ dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index acb84d36..309a3102 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -36,6 +36,8 @@ namespace Opm PhaseVec phase_pressure_; PhaseVec phase_volume_density_; Scalar total_phase_volume_density_; + PhaseVec volume_formation_factor_; + PhaseVec solution_factor_; Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering PhaseVec saturation_; PhaseVec phase_compressibility_; diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 76c6edd6..9a44ba66 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -154,11 +154,11 @@ public: // Get B and R factors. const PhaseVec& p = fluid_state.phase_pressure_; const CompVec& z = fluid_state.surface_volume_; - double B[3]; + PhaseVec& B = fluid_state.volume_formation_factor_; B[Aqua] = params().pvt_.B(p[Aqua], z, Aqua); B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); - double R[3]; // Only using 2 of them, though. + PhaseVec& R = fluid_state.solution_factor_; R[Vapour] = params().pvt_.R(p[Vapour], z, Vapour); R[Liquid] = params().pvt_.R(p[Liquid], z, Liquid); // Set the A matrix (A = RB^{-1}) From 055e0e967d01062781e5f6f081ff962315c62f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 13:04:20 +0200 Subject: [PATCH 065/113] Added program that writes fluid info in the (zg/zo, p) plane to matlab format. --- .../blackoil/test/bo_fluid_p_and_z_deps.cpp | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp diff --git a/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp b/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp new file mode 100644 index 00000000..ad006ab5 --- /dev/null +++ b/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp @@ -0,0 +1,126 @@ +/* + Copyright 2011 SINTEF ICT, Applied Mathematics. + + 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 . +*/ + + +#include "config.h" + +#include +#include +#include + + +int main(int argc, char** argv) +{ + std::cout << "%{\n"; + + // Parameters. + Dune::parameter::ParameterGroup param(argc, argv); + + // Parser. + std::string ecl_file = param.get("filename"); + Dune::EclipseGridParser parser(ecl_file); + // Look at the BlackoilFluid behaviour + Opm::BlackoilFluid fluid; + fluid.init(parser); + Opm::BlackoilFluid::CompVec z0(0.0); + z0[Opm::BlackoilFluid::Water] = param.getDefault("z_w", 0.0); + z0[Opm::BlackoilFluid::Oil] = param.getDefault("z_o", 1.0); + z0[Opm::BlackoilFluid::Gas] = param.getDefault("z_g", 0.0); + int num_pts_p = param.getDefault("num_pts_p", 41); + int num_pts_z = param.getDefault("num_pts_z", 51); + double min_press = param.getDefault("min_press", 1e7); + double max_press = param.getDefault("max_press", 3e7); + int changing_component = param.getDefault("changing_component", int(Opm::BlackoilFluid::Gas)); + double min_z = param.getDefault("min_z", 0.0); + double max_z = param.getDefault("max_z", 500.0); + int variable = param.getDefault("variable", 0); + Opm::BlackoilFluid::CompVec z = z0; + std::cout << "%}\n" + << "data = [\n"; + + for (int i = 0; i < num_pts_p; ++i) { + double pfactor = num_pts_p < 2 ? 0.0 : double(i)/double(num_pts_p - 1); + double p = (1.0 - pfactor)*min_press + pfactor*max_press; + for (int j = 0; j < num_pts_z; ++j) { + double zfactor = num_pts_z < 2 ? 0.0 : double(j)/double(num_pts_z - 1); + z[changing_component] = (1.0 - zfactor)*min_z + zfactor*max_z; +// std::cout << p << ' ' << z << '\n'; + Opm::BlackoilFluid::FluidState state = fluid.computeState(Opm::BlackoilFluid::PhaseVec(p), z); + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + double var = 0.0; + switch (variable) { + case 0: + var = state.total_compressibility_; + break; + case 1: + var = state.experimental_term_; + break; + case 2: + var = state.saturation_[0]; + break; + case 3: + var = state.saturation_[1]; + break; + case 4: + var = state.saturation_[2]; + break; + case 5: + var = state.volume_formation_factor_[0]; + break; + case 6: + var = state.volume_formation_factor_[1]; + break; + case 7: + var = state.volume_formation_factor_[2]; + break; + case 8: + var = state.solution_factor_[0]; + break; + case 9: + var = state.solution_factor_[1]; + break; + case 10: + var = state.solution_factor_[2]; + break; + default: + THROW("Unknown varable specification: " << variable); + break; + } + std::cout << var << ' '; + } + std::cout << '\n'; + } + std::cout << "];\n\n" + << "paxis = [\n"; + for (int i = 0; i < num_pts_p; ++i) { + double pfactor = double(i)/double(num_pts_p - 1); + double p = (1.0 - pfactor)*min_press + pfactor*max_press; + std::cout << p << '\n'; + } + std::cout << "];\n\n" + << "zaxis = [\n"; + for (int j = 0; j < num_pts_z; ++j) { + double zfactor = double(j)/double(num_pts_z - 1); + std::cout << (1.0 - zfactor)*min_z + zfactor*max_z << '\n'; + } + std::cout << "];\n"; +} + From b834757d1256ba68a09079a42a66fa7b7a6ead8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 14:05:52 +0200 Subject: [PATCH 066/113] Changed extrapolation behaviour outside tabulated R and pressure values. --- .../blackoil/fluid/MiscibilityLiveOil.cpp | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index cc97f91b..c1402f36 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -233,17 +233,10 @@ namespace Opm press); } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[3], maxR); - if (undersat_oil_tables_[is][0].size() < 2) { // Not anymore ... - double val = (saturated_oil_table_[item][is+1] - - saturated_oil_table_[item][is]) / - (saturated_oil_table_[0][is+1] - - saturated_oil_table_[0][is]); - - return val; - } double w = (maxR - saturated_oil_table_[3][is]) / (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); - + ASSERT(undersat_oil_tables_[is][0].size() >= 2); + ASSERT(undersat_oil_tables_[is+1][0].size() >= 2); double val1 = linearInterpolDerivative(undersat_oil_tables_[is][0], undersat_oil_tables_[is][item], @@ -261,33 +254,12 @@ namespace Opm saturated_oil_table_[item], press); } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[3], maxR); - - // Extrapolate from first table section - if (is == 0 && press < saturated_oil_table_[0][0]) { - return linearInterpolationExtrap(undersat_oil_tables_[0][0], - undersat_oil_tables_[0][item], - press); - } - - // Extrapolate from last table section - int ltp = saturated_oil_table_[0].size() - 1; - if (is+1 == ltp && press > saturated_oil_table_[0][ltp]) { - return linearInterpolationExtrap(undersat_oil_tables_[ltp][0], - undersat_oil_tables_[ltp][item], - press); - } - // Interpolate between table sections + int is = tableIndex(saturated_oil_table_[3], maxR); double w = (maxR - saturated_oil_table_[3][is]) / - (saturated_oil_table_[3][is+1] - - saturated_oil_table_[3][is]); - if (undersat_oil_tables_[is][0].size() < 2) { // Not anymore ... - double val = saturated_oil_table_[item][is] + - w*(saturated_oil_table_[item][is+1] - - saturated_oil_table_[item][is]); - return val; - } + (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); + ASSERT(undersat_oil_tables_[is][0].size() >= 2); + ASSERT(undersat_oil_tables_[is+1][0].size() >= 2); double val1 = linearInterpolationExtrap(undersat_oil_tables_[is][0], undersat_oil_tables_[is][item], From 9d1d59a5703155245aff9aaa650f1bb8fabecaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:03:46 +0200 Subject: [PATCH 067/113] New abstract interface computing vectors of properties. --- .../blackoil/fluid/MiscibilityProps.hpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp index 693f87ec..2bbacf33 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityProps.hpp @@ -56,6 +56,29 @@ namespace Opm virtual double dBdp(int region, double press, const surfvol_t& surfvol) const = 0; virtual double R (int region, double press, const surfvol_t& surfvol) const = 0; virtual double dRdp(int region, double press, const surfvol_t& surfvol) const = 0; + + virtual void getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const = 0; + virtual void B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const = 0; + virtual void dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const = 0; + virtual void R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const = 0; + virtual void dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const = 0; }; } // namespace Opm From 0ea2c1d7543d2bb34d40ae8d1dcc3b2c782775e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:04:15 +0200 Subject: [PATCH 068/113] Implemented new fluid interface. --- .../blackoil/fluid/MiscibilityWater.hpp | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index 8dd60032..5553ada5 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -46,6 +46,7 @@ namespace Opm { public: typedef std::vector > table_t; + MiscibilityWater(const table_t& pvtw) { const int region_number = 0; @@ -60,6 +61,7 @@ namespace Opm THROW("MiscibilityWater does not support 'viscosibility'."); } } + MiscibilityWater(double visc) : ref_press_(0.0), ref_B_(1.0), @@ -67,6 +69,7 @@ namespace Opm viscosity_(visc) { } + virtual ~MiscibilityWater() { } @@ -75,6 +78,17 @@ namespace Opm { return viscosity_; } + + virtual void getViscosity(const std::vector& pressures, + const std::vector&, + int, + std::vector& output) const + { + int num = pressures.size(); + output.clear(); + output.resize(num, viscosity_); + } + virtual double B(int /*region*/, double press, const surfvol_t& /*surfvol*/) const { if (comp_) { @@ -85,6 +99,26 @@ namespace Opm return ref_B_; } } + + virtual void B(const std::vector& pressures, + const std::vector&, + int phase, + std::vector& output) const + { + int num = pressures.size(); + if (comp_) { + output.resize(num); + for (int i = 0; i < num; ++i) { + // Computing a polynomial approximation to the exponential. + double x = comp_*(pressures[i][phase] - ref_press_); + output[i] = ref_B_/(1.0 + x + 0.5*x*x); + } + } else { + output.clear(); + output.resize(num, ref_B_); + } + } + virtual double dBdp(int region, double press, const surfvol_t& surfvol) const { if (comp_) { @@ -93,14 +127,59 @@ namespace Opm return 0.0; } } + + virtual void dBdp(const std::vector& pressures, + const std::vector& surfvols, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const + { + B(pressures, surfvols, phase, output_B); + int num = pressures.size(); + if (comp_) { + output_dBdp.resize(num); + for (int i = 0; i < num; ++i) { + output_dBdp[i] = -comp_*output_B[i]; + } + } else { + output_dBdp.clear(); + output_dBdp.resize(num, 0.0); + } + } + virtual double R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const { return 0.0; } + + virtual void R(const std::vector& pressures, + const std::vector&, + int, + std::vector& output) const + { + int num = pressures.size(); + output.clear(); + output.resize(num, 0.0); + } + virtual double dRdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const { return 0.0; } + + virtual void dRdp(const std::vector& pressures, + const std::vector&, + int, + std::vector& output_R, + std::vector& output_dRdp) const + { + int num = pressures.size(); + output_R.clear(); + output_R.resize(num, 0.0); + output_dRdp.clear(); + output_dRdp.resize(num, 0.0); + } + private: double ref_press_; double ref_B_; From 40d6b42d56fe908f8bfbbd7b04ff2468a212066c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:04:37 +0200 Subject: [PATCH 069/113] Implemented new interface. --- .../porsol/blackoil/fluid/MiscibilityDead.cpp | 61 +++++++++++++++++++ .../porsol/blackoil/fluid/MiscibilityDead.hpp | 24 +++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 4eaf447a..5a4aa6c2 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -87,6 +87,17 @@ namespace Opm return viscosity_(press); } + void MiscibilityDead::getViscosity(const std::vector& pressures, + const std::vector&, + int phase, + std::vector& output) const + { + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = viscosity_(pressures[i][phase]); + } + } double MiscibilityDead::B(int region, double press, const surfvol_t& /*surfvol*/) const { @@ -94,6 +105,18 @@ namespace Opm return 1.0/one_over_B_(press); } + void MiscibilityDead::B(const std::vector& pressures, + const std::vector&, + int phase, + std::vector& output) const + { + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = 1.0/one_over_B_(pressures[i][phase]); + } + } + double MiscibilityDead::dBdp(int region, double press, const surfvol_t& /*surfvol*/) const { // Interpolate 1/B @@ -102,14 +125,52 @@ namespace Opm return -Bg*Bg*one_over_B_.derivative(press); } + void MiscibilityDead::dBdp(const std::vector& pressures, + const std::vector& surfvols, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const + { + B(pressures, surfvols, phase, output_B); + int num = pressures.size(); + output_dBdp.resize(num); + for (int i = 0; i < num; ++i) { + double Bg = output_B[i]; + output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(pressures[i][phase]); + } + } + double MiscibilityDead::R(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const { return 0.0; } + void MiscibilityDead::R(const std::vector& pressures, + const std::vector&, + int, + std::vector& output) const + { + int num = pressures.size(); + output.clear(); + output.resize(num, 0.0); + } + double MiscibilityDead::dRdp(int /*region*/, double /*press*/, const surfvol_t& /*surfvol*/) const { return 0.0; } + void MiscibilityDead::dRdp(const std::vector& pressures, + const std::vector&, + int, + std::vector& output_R, + std::vector& output_dRdp) const + { + int num = pressures.size(); + output_R.clear(); + output_R.resize(num, 0.0); + output_dRdp.clear(); + output_dRdp.resize(num, 0.0); + } + } diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp index 1d9d764b..8962bd58 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.hpp @@ -53,7 +53,29 @@ namespace Opm virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; virtual double R(int region, double press, const surfvol_t& surfvol) const; virtual double dRdp(int region, double press, const surfvol_t& surfvol) const; - + + virtual void getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const; + virtual void R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const; private: // PVT properties of dry gas or dead oil From 3e96ed4502858e74ffea2b59bf14a88d2dc8169e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:46:01 +0200 Subject: [PATCH 070/113] Implemented new interface. --- .../blackoil/fluid/MiscibilityLiveOil.cpp | 69 +++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveOil.hpp | 23 +++++++ 2 files changed, 92 insertions(+) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index c1402f36..abf1902d 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -174,6 +174,19 @@ namespace Opm return miscible_oil(press, surfvol, 2, false); } + void MiscibilityLiveOil::getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = miscible_oil(pressures[i][phase], surfvol[i], 2, false); + } + } + // Dissolved gas-oil ratio double MiscibilityLiveOil::R(int /*region*/, double press, const surfvol_t& surfvol) const { @@ -190,6 +203,19 @@ namespace Opm } } + void MiscibilityLiveOil::R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = R(0, pressures[i][phase], surfvol[i]); + } + } + // Dissolved gas-oil ratio derivative double MiscibilityLiveOil::dRdp(int /*region*/, double press, const surfvol_t& surfvol) const { @@ -205,12 +231,40 @@ namespace Opm } } + void MiscibilityLiveOil::dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const + { + ASSERT(pressures.size() == surfvol.size()); + R(pressures, surfvol, phase, output_R); + int num = pressures.size(); + output_dRdp.resize(num); + for (int i = 0; i < num; ++i) { + output_dRdp[i] = dRdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R. + } + } + double MiscibilityLiveOil::B(int /*region*/, double press, const surfvol_t& surfvol) const { // if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. return 1.0/miscible_oil(press, surfvol, 1, false); } + void MiscibilityLiveOil::B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = B(0, pressures[i][phase], surfvol[i]); + } + } + double MiscibilityLiveOil::dBdp(int region, double press, const surfvol_t& surfvol) const { // if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case. @@ -218,6 +272,21 @@ namespace Opm return -Bo*Bo*miscible_oil(press, surfvol, 1, true); } + void MiscibilityLiveOil::dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const + { + ASSERT(pressures.size() == surfvol.size()); + B(pressures, surfvol, phase, output_B); + int num = pressures.size(); + output_dBdp.resize(num); + for (int i = 0; i < num; ++i) { + output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R. + } + } + double MiscibilityLiveOil::miscible_oil(double press, const surfvol_t& surfvol, int item, bool deriv) const { diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp index fb3abdd0..103012f1 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -53,6 +53,29 @@ namespace Opm virtual double B (int region, double press, const surfvol_t& surfvol) const; virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; + virtual void getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const; + virtual void R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const; + protected: // item: 1=B 2=mu; double miscible_oil(double press, const surfvol_t& surfvol, int item, From abebf165b2c400d820a2c807a2996d1a00480098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:57:18 +0200 Subject: [PATCH 071/113] Implemented new interface. --- .../blackoil/fluid/MiscibilityLiveGas.cpp | 69 +++++++++++++++++++ .../blackoil/fluid/MiscibilityLiveGas.hpp | 23 +++++++ 2 files changed, 92 insertions(+) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp index 51293fb4..3d44239a 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp @@ -90,6 +90,19 @@ namespace Opm return miscible_gas(press, surfvol, 2, false); } + void MiscibilityLiveGas::getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = miscible_gas(pressures[i][phase], surfvol[i], 2, false); + } + } + // Vaporised oil-gas ratio. double MiscibilityLiveGas::R(int /*region*/, double press, const surfvol_t& surfvol) const { @@ -106,6 +119,19 @@ namespace Opm } } + void MiscibilityLiveGas::R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = R(0, pressures[i][phase], surfvol[i]); + } + } + // Vaporised oil-gas ratio derivative double MiscibilityLiveGas::dRdp(int /*region*/, double press, const surfvol_t& surfvol) const { @@ -121,18 +147,61 @@ namespace Opm } } + void MiscibilityLiveGas::dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const + { + ASSERT(pressures.size() == surfvol.size()); + R(pressures, surfvol, phase, output_R); + int num = pressures.size(); + output_dRdp.resize(num); + for (int i = 0; i < num; ++i) { + output_dRdp[i] = dRdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R. + } + } + double MiscibilityLiveGas::B(int /*region*/, double press, const surfvol_t& surfvol) const { if (surfvol[Vapour] == 0.0) return 1.0; // To handle no-gas case. return miscible_gas(press, surfvol, 1, false); } + void MiscibilityLiveGas::B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const + { + ASSERT(pressures.size() == surfvol.size()); + int num = pressures.size(); + output.resize(num); + for (int i = 0; i < num; ++i) { + output[i] = B(0, pressures[i][phase], surfvol[i]); + } + } + double MiscibilityLiveGas::dBdp(int /*region*/, double press, const surfvol_t& surfvol) const { if (surfvol[Vapour] == 0.0) return 0.0; // To handle no-gas case. return miscible_gas(press, surfvol, 1, true); } + void MiscibilityLiveGas::dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const + { + ASSERT(pressures.size() == surfvol.size()); + B(pressures, surfvol, phase, output_B); + int num = pressures.size(); + output_dBdp.resize(num); + for (int i = 0; i < num; ++i) { + output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated B. + } + } + double MiscibilityLiveGas::miscible_gas(double press, const surfvol_t& surfvol, int item, bool deriv) const { diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp index 08dfc907..801649ed 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp @@ -53,6 +53,29 @@ namespace Opm virtual double B(int region, double press, const surfvol_t& surfvol) const; virtual double dBdp(int region, double press, const surfvol_t& surfvol) const; + virtual void getViscosity(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void B(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dBdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_B, + std::vector& output_dBdp) const; + virtual void R(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output) const; + virtual void dRdp(const std::vector& pressures, + const std::vector& surfvol, + int phase, + std::vector& output_R, + std::vector& output_dRdp) const; + protected: // item: 1=B 2=mu; double miscible_gas(double press, const surfvol_t& surfvol, int item, From 5378d429a2f1bb08fbf7b0e5e296a4a998be5381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 15:57:39 +0200 Subject: [PATCH 072/113] Add a todo comment. --- dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index abf1902d..6f5cc930 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -268,7 +268,7 @@ namespace Opm double MiscibilityLiveOil::dBdp(int region, double press, const surfvol_t& surfvol) const { // if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case. - double Bo = B(region, press, surfvol); + double Bo = B(region, press, surfvol); // \TODO check if we incur virtual call overhead here. return -Bo*Bo*miscible_oil(press, surfvol, 1, true); } @@ -283,7 +283,7 @@ namespace Opm int num = pressures.size(); output_dBdp.resize(num); for (int i = 0; i < num; ++i) { - output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R. + output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated B. } } From b418185aeb30cd533dc8afeb9583c7eedb0bd4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 17 Jun 2011 20:27:42 +0200 Subject: [PATCH 073/113] Implemented vectorized fluid methods in BlackoilPVT. --- dune/porsol/blackoil/fluid/BlackoilPVT.cpp | 76 ++++++++++++++++++++++ dune/porsol/blackoil/fluid/BlackoilPVT.hpp | 19 ++++++ 2 files changed, 95 insertions(+) diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp index 88221541..c35029f0 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.cpp @@ -123,4 +123,80 @@ namespace Opm } } + void BlackoilPVT::getViscosity(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const + { + int num = pressures.size(); + output.resize(num); + for (int phase = 0; phase < numPhases; ++phase) { + propsForPhase(PhaseIndex(phase)).getViscosity(pressures, surfvol, phase, data1_); + for (int i = 0; i < num; ++i) { + output[i][phase] = data1_[i]; + } + } + } + + void BlackoilPVT::B(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const + { + int num = pressures.size(); + output.resize(num); + for (int phase = 0; phase < numPhases; ++phase) { + propsForPhase(PhaseIndex(phase)).B(pressures, surfvol, phase, data1_); + for (int i = 0; i < num; ++i) { + output[i][phase] = data1_[i]; + } + } + } + + void BlackoilPVT::dBdp(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output_B, + std::vector& output_dBdp) const + { + int num = pressures.size(); + output_B.resize(num); + output_dBdp.resize(num); + for (int phase = 0; phase < numPhases; ++phase) { + propsForPhase(PhaseIndex(phase)).dBdp(pressures, surfvol, phase, data1_, data2_); + for (int i = 0; i < num; ++i) { + output_B[i][phase] = data1_[i]; + output_dBdp[i][phase] = data2_[i]; + } + } + } + + void BlackoilPVT::R(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const + { + int num = pressures.size(); + output.resize(num); + for (int phase = 0; phase < numPhases; ++phase) { + propsForPhase(PhaseIndex(phase)).R(pressures, surfvol, phase, data1_); + for (int i = 0; i < num; ++i) { + output[i][phase] = data1_[i]; + } + } + } + + void BlackoilPVT::dRdp(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output_R, + std::vector& output_dRdp) const + { + int num = pressures.size(); + output_R.resize(num); + output_dRdp.resize(num); + for (int phase = 0; phase < numPhases; ++phase) { + propsForPhase(PhaseIndex(phase)).dRdp(pressures, surfvol, phase, data1_, data2_); + for (int i = 0; i < num; ++i) { + output_R[i][phase] = data1_[i]; + output_dRdp[i][phase] = data2_[i]; + } + } + } + } // namespace Opm diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp index 0563daab..d5469223 100644 --- a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilPVT.hpp @@ -52,6 +52,23 @@ namespace Opm const CompVec& surfvol, PhaseIndex phase) const; + void getViscosity(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const; + void B(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const; + void dBdp(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output_B, + std::vector& output_dBdp) const; + void R(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output) const; + void dRdp(const std::vector& pressures, + const std::vector& surfvol, + std::vector& output_R, + std::vector& output_dRdp) const; private: int region_number_; @@ -61,6 +78,8 @@ namespace Opm boost::scoped_ptr oil_props_; boost::scoped_ptr gas_props_; CompVec densities_; + mutable std::vector data1_; + mutable std::vector data2_; }; } From 6f31f9978a2c37b1c31e224274227d2794190c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:13:45 +0200 Subject: [PATCH 074/113] Added a static assertation and two matrix types. --- dune/porsol/blackoil/fluid/BlackoilDefs.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp index 091e92b9..e6e4afcb 100644 --- a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp +++ b/dune/porsol/blackoil/fluid/BlackoilDefs.hpp @@ -22,7 +22,8 @@ #include - +#include +#include namespace Opm { @@ -39,6 +40,9 @@ namespace Opm typedef double Scalar; typedef Dune::FieldVector CompVec; typedef Dune::FieldVector PhaseVec; + BOOST_STATIC_ASSERT(int(numComponents) == int(numPhases)); + typedef Dune::FieldMatrix PhaseToCompMatrix; + typedef Dune::FieldMatrix PhaseJacobian; }; } // namespace Opm From aafc500db0619440acbeb39071166667ebd871bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:15:39 +0200 Subject: [PATCH 075/113] Added ManyFluidStatesBlackoil, corrected name of a field. --- .../blackoil/fluid/FluidStateBlackoil.hpp | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 309a3102..27eae606 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -27,7 +27,7 @@ namespace Opm { /*! - * \brief Fluid states for a black oil model. + * \brief Fluid state for a black oil model. */ struct FluidStateBlackoil : public BlackoilDefs { @@ -36,7 +36,7 @@ namespace Opm PhaseVec phase_pressure_; PhaseVec phase_volume_density_; Scalar total_phase_volume_density_; - PhaseVec volume_formation_factor_; + PhaseVec formation_volume_factor_; PhaseVec solution_factor_; Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering PhaseVec saturation_; @@ -50,6 +50,30 @@ namespace Opm Dune::FieldVector, numPhases> dmobility_; }; + /*! + * \brief Multiple fluid states for a black oil model. + */ + struct ManyFluidStatesBlackoil : public BlackoilDefs + { + std::vector temperature_; + std::vector surface_volume_; + std::vector phase_pressure_; + std::vector phase_volume_density_; + std::vector total_phase_volume_density_; + std::vector formation_volume_factor_; + std::vector solution_factor_; + std::vector phase_to_comp_; // RB^{-1} in Fortran ordering + std::vector saturation_; + std::vector phase_compressibility_; + std::vector total_compressibility_; + std::vector experimental_term_; + std::vector viscosity_; + std::vector relperm_; + std::vector drelperm_; + std::vector mobility_; + std::vector dmobility_; + }; + } // end namespace Opm From 1f9ed4421e0f0dca7f85d260f00273b738009f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:16:23 +0200 Subject: [PATCH 076/113] Adapt to change of field name in FluidStateBlackoil. --- dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp b/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp index ad006ab5..3d1a5aaa 100644 --- a/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp @@ -83,13 +83,13 @@ int main(int argc, char** argv) var = state.saturation_[2]; break; case 5: - var = state.volume_formation_factor_[0]; + var = state.formation_volume_factor_[0]; break; case 6: - var = state.volume_formation_factor_[1]; + var = state.formation_volume_factor_[1]; break; case 7: - var = state.volume_formation_factor_[2]; + var = state.formation_volume_factor_[2]; break; case 8: var = state.solution_factor_[0]; From 7cbcad0c3e5e2f761eda4a2f814e0dbcfe1e6e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:16:46 +0200 Subject: [PATCH 077/113] Implemented computeManyEquilibria() method. --- .../blackoil/fluid/FluidSystemBlackoil.hpp | 95 ++++++++++++++++++- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 9a44ba66..60e1aee8 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -154,7 +154,7 @@ public: // Get B and R factors. const PhaseVec& p = fluid_state.phase_pressure_; const CompVec& z = fluid_state.surface_volume_; - PhaseVec& B = fluid_state.volume_formation_factor_; + PhaseVec& B = fluid_state.formation_volume_factor_; B[Aqua] = params().pvt_.B(p[Aqua], z, Aqua); B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); @@ -181,8 +181,8 @@ public: // Update saturations. double sumu = fluid_state.total_phase_volume_density_; PhaseVec& s = fluid_state.saturation_; - for (int i = 0; i < 3; ++i) { - s[i] = u[i]/sumu; + for (int phase = 0; phase < numPhases; ++phase) { + s[phase] = u[phase]/sumu; } // Compute viscosities. @@ -229,6 +229,93 @@ public: fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; } + /*! + * \brief Assuming the surface volumes and the pressures of all + * phases are known, compute everything except relperm and + * mobility. + */ + template + static void computeManyEquilibria(ManyFluidStates& fluid_state) + { + // Get B and R factors, viscosities Vectorized at lower level. + const std::vector& pv = fluid_state.phase_pressure_; + const std::vector& zv = fluid_state.surface_volume_; + std::vector& Bv = fluid_state.volume_formation_factor_; + std::vector dBv; + params().pvt_.dBdp(pv, zv, Bv, dBv); + std::vector& Rv = fluid_state.solution_factor_; + std::vector dRv; + params().pvt_.dRdp(pv, zv, Rv, dRv); + std::vector& muv = fluid_state.viscosity_; + params().pvt_.getViscosity(pv, zv, muv); + + // The rest is vectorized in this function. + int num = pv.size(); + fluid_state.phase_to_comp.resize(num); + for (int i = 0; i < num; ++i) { + // Convenience vars. + const PhaseVec& B = Bv[i]; + const PhaseVec& dB = dBv[i]; + const PhaseVec& R = Rv[i]; + const PhaseVec& dR = dRv[i]; + const CompVec& z = zv[i]; + + // Set the A matrix (A = RB^{-1}) + Dune::SharedFortranMatrix A(numComponents, numPhases, &fluid_state.phase_to_comp_[i][0][0]); + zero(A); + A(Water, Aqua) = 1.0/B[Aqua]; + A(Gas, Vapour) = 1.0/B[Vapour]; + A(Gas, Liquid) = R[Liquid]/B[Liquid]; + A(Oil, Vapour) = R[Vapour]/B[Vapour]; + A(Oil, Liquid) = 1.0/B[Liquid]; + + // Update phase volumes. This is the same as multiplying with A^{-1} + PhaseVec& u = fluid_state.phase_volume_density_[i]; + double detR = 1.0 - R[Vapour]*R[Liquid]; + u[Aqua] = B[Aqua]*z[Water]; + u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; + u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; + fluid_state.total_phase_volume_density_[i] = u[Aqua] + u[Vapour] + u[Liquid]; + + // Update saturations. + double sumu = fluid_state.total_phase_volume_density_[i]; + PhaseVec& s = fluid_state.saturation_[i]; + for (int phase = 0; phase < numPhases; ++phase) { + s[phase] = u[phase]/sumu; + } + + // Phase compressibilities. + PhaseVec& cp = fluid_state.phase_compressibility_[i]; + // Set the derivative of the A matrix (A = RB^{-1}) + double data_for_dA[numComponents*numPhases]; + Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); + zero(dA); + dA(Water, Aqua) = -dB[Aqua]/(B[Aqua]*B[Aqua]); + dA(Gas, Vapour) = -dB[Vapour]/(B[Vapour]*B[Vapour]); + dA(Oil, Liquid) = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. + dA(Gas, Liquid) = dA(Oil, Liquid)*R[Liquid] + dR[Liquid]/B[Liquid]; + dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; + double data_for_Ai[numComponents*numPhases]; + Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); + // Ai = A; // This does not make a deep copy. + std::copy(A.data(), A.data() + numComponents*numPhases, Ai.data()); + Dune::invert(Ai); + double data_for_C[numComponents*numPhases]; + Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); + Dune::prod(Ai, dA, C); + //CompVec ones(1.0); + //cp = Dune::prod(C, ones); // Probably C' and not C; we want phasewise compressibilities: + cp[Aqua] = C(Water, Aqua); + cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); + cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); + fluid_state.total_compressibility_[i] = cp*s; + + // Experimental term. + PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); + fluid_state.experimental_term_[i] = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; + } + } + /*! * \brief Returns the activity coefficient of a component in a * phase. @@ -307,7 +394,7 @@ private: static Params& params() { - static Params params; + static Params params; // \TODO: Replace singleton here by something more thread-robust? return params; } }; From 5859573b86c0b59b2f8013e6b2b719e691b888cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:27:24 +0200 Subject: [PATCH 078/113] Fixed typos. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 60e1aee8..2965d5b5 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -240,7 +240,7 @@ public: // Get B and R factors, viscosities Vectorized at lower level. const std::vector& pv = fluid_state.phase_pressure_; const std::vector& zv = fluid_state.surface_volume_; - std::vector& Bv = fluid_state.volume_formation_factor_; + std::vector& Bv = fluid_state.formation_volume_factor_; std::vector dBv; params().pvt_.dBdp(pv, zv, Bv, dBv); std::vector& Rv = fluid_state.solution_factor_; @@ -251,7 +251,7 @@ public: // The rest is vectorized in this function. int num = pv.size(); - fluid_state.phase_to_comp.resize(num); + fluid_state.phase_to_comp_.resize(num); for (int i = 0; i < num; ++i) { // Convenience vars. const PhaseVec& B = Bv[i]; From 55a9d8288713ac3f382203e890f7aa4c86dd6c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 11:27:47 +0200 Subject: [PATCH 079/113] Implemented computeManyStates(). --- dune/porsol/blackoil/BlackoilFluid.hpp | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index da04b4b7..2300a76c 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -54,6 +54,7 @@ namespace Opm surface_densities_[Water] = dens[1]; surface_densities_[Gas] = dens[2]; } + FluidState computeState(PhaseVec phase_pressure, CompVec z) const { FluidState state; @@ -66,11 +67,42 @@ namespace Opm for (int phase = 0; phase < numPhases; ++phase) { state.mobility_[phase] = state.relperm_[phase]/state.viscosity_[phase]; for (int p2 = 0; p2 < numPhases; ++p2) { + // Ignoring pressure variation in viscosity for this one. state.dmobility_[phase][p2] = state.drelperm_[phase][p2]/state.viscosity_[phase]; } } return state; } + + void computeManyStates(const std::vector& phase_pressure, + const std::vector& z, + ManyFluidStatesBlackoil& state) const + { + int num = phase_pressure.size(); + state.temperature_.clear(); + state.temperature_.resize(num, 300.0); + state.phase_pressure_ = phase_pressure; + state.surface_volume_ = z; + FluidSystemBlackoil<>::computeManyEquilibria(state); // Sets everything but relperm and mobility. + state.relperm_.resize(num); + state.drelperm_.resize(num); + state.mobility_.resize(num); + state.dmobility_.resize(num); + for (int i = 0; i < num; ++i) { + FluidMatrixInteractionBlackoil::kr(state.relperm_[i], fmi_params_, + state.saturation_[i], state.temperature_[i]); + FluidMatrixInteractionBlackoil::dkr(state.drelperm_[i], fmi_params_, + state.saturation_[i], state.temperature_[i]); + for (int phase = 0; phase < numPhases; ++phase) { + state.mobility_[i][phase] = state.relperm_[i][phase]/state.viscosity_[i][phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + // Ignoring pressure variation in viscosity for this one. + state.dmobility_[i][phase][p2] = state.drelperm_[i][phase][p2]/state.viscosity_[i][phase]; + } + } + } + } + const CompVec& surfaceDensities() const { return surface_densities_; From 87d45453de97ab15ee5908fb45b3d5939aca2cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 13:28:13 +0200 Subject: [PATCH 080/113] Changed some types to those defined in BlackoilDefs.hpp. --- dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 27eae606..9c539664 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -38,16 +38,16 @@ namespace Opm Scalar total_phase_volume_density_; PhaseVec formation_volume_factor_; PhaseVec solution_factor_; - Scalar phase_to_comp_[numPhases*numComponents]; // RB^{-1} in Fortran ordering + PhaseToCompMatrix phase_to_comp_; // RB^{-1} in Fortran ordering PhaseVec saturation_; PhaseVec phase_compressibility_; Scalar total_compressibility_; Scalar experimental_term_; PhaseVec viscosity_; PhaseVec relperm_; - Dune::FieldVector, numPhases> drelperm_; + PhaseJacobian drelperm_; PhaseVec mobility_; - Dune::FieldVector, numPhases> dmobility_; + PhaseJacobian dmobility_; }; /*! From 995d6542bd5723bc4e71b6ffc8446cc9b1008503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 13:30:08 +0200 Subject: [PATCH 081/113] Remember resizing data vectors. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index 2965d5b5..dcc6e218 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -162,7 +162,7 @@ public: R[Vapour] = params().pvt_.R(p[Vapour], z, Vapour); R[Liquid] = params().pvt_.R(p[Liquid], z, Liquid); // Set the A matrix (A = RB^{-1}) - Dune::SharedFortranMatrix A(numComponents, numPhases, fluid_state.phase_to_comp_); + Dune::SharedFortranMatrix A(numComponents, numPhases, &fluid_state.phase_to_comp_[0][0]); zero(A); A(Water, Aqua) = 1.0/B[Aqua]; A(Gas, Vapour) = 1.0/B[Vapour]; @@ -237,7 +237,7 @@ public: template static void computeManyEquilibria(ManyFluidStates& fluid_state) { - // Get B and R factors, viscosities Vectorized at lower level. + // Get B and R factors, viscosities. Vectorized at lower level. const std::vector& pv = fluid_state.phase_pressure_; const std::vector& zv = fluid_state.surface_volume_; std::vector& Bv = fluid_state.formation_volume_factor_; @@ -252,6 +252,13 @@ public: // The rest is vectorized in this function. int num = pv.size(); fluid_state.phase_to_comp_.resize(num); + fluid_state.phase_volume_density_.resize(num); + fluid_state.total_phase_volume_density_.resize(num); + fluid_state.phase_to_comp_.resize(num); + fluid_state.saturation_.resize(num); + fluid_state.phase_compressibility_.resize(num); + fluid_state.total_compressibility_.resize(num); + fluid_state.experimental_term_.resize(num); for (int i = 0; i < num; ++i) { // Convenience vars. const PhaseVec& B = Bv[i]; From a9add0f757e33eacdded90de7754f538a6cfa2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 13:30:42 +0200 Subject: [PATCH 082/113] Implemented computeNew() [temporary name], which uses the new vectorized interfaces. --- dune/porsol/blackoil/BlackoilFluid.hpp | 182 ++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 5 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 2300a76c..887f777c 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -88,6 +88,7 @@ namespace Opm state.drelperm_.resize(num); state.mobility_.resize(num); state.dmobility_.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { FluidMatrixInteractionBlackoil::kr(state.relperm_[i], fmi_params_, state.saturation_[i], state.temperature_[i]); @@ -151,8 +152,7 @@ namespace Opm std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). std::vector phasemobc; // Phase mobilities per cell. std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). - typedef Dune::FieldVector, numPhases> PhaseMat; - std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. + std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. public: @@ -205,7 +205,7 @@ namespace Opm viscosity[cell] = state.viscosity_; phasemobc[cell] = state.mobility_; phasemobc_deriv[cell] = state.dmobility_; - std::copy(state.phase_to_comp_, state.phase_to_comp_ + nc*np, &cellA[cell*nc*np]); + std::copy(&state.phase_to_comp_[0][0], &state.phase_to_comp_[0][0] + nc*np, &cellA[cell*nc*np]); // Fractional flow must be calculated. double total_mobility = 0.0; for (int phase = 0; phase < numPhases; ++phase) { @@ -270,7 +270,7 @@ namespace Opm CompVec face_z(0.0); double face_z_factor = 0.5; PhaseVec phase_mob[2]; - PhaseMat phasemob_deriv[2]; + PhaseJacobian phasemob_deriv[2]; for (int j = 0; j < 2; ++j) { if (c[j] >= 0) { face_z += cell_z[c[j]]; @@ -313,9 +313,181 @@ namespace Opm // Find faceA. FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); - std::copy(face_state.phase_to_comp_, face_state.phase_to_comp_ + nc*np, &faceA[face*nc*np]); + std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); } } + + + + + public: + template + void computeNew(const Grid& grid, + const Rock& rock, + const BlackoilFluid& fluid, + const typename Grid::Vector gravity, + const std::vector& cell_pressure, + const std::vector& face_pressure, + const std::vector& cell_z, + const CompVec& bdy_z, + const double dt) + { + int num_cells = cell_z.size(); + ASSERT(num_cells == grid.numCells()); + int num_faces = face_pressure.size(); + ASSERT(num_faces == grid.numFaces()); + const int np = numPhases; + const int nc = numComponents; + bool nonzero_gravity = gravity.two_norm() > 0.0; + BOOST_STATIC_ASSERT(np == nc); + totcompr.resize(num_cells); + totphasevol_density.resize(num_cells); + voldiscr.resize(num_cells); + relvoldiscr.resize(num_cells); + saturation.resize(num_cells); + frac_flow.resize(num_cells); + rel_perm.resize(num_cells); + viscosity.resize(num_cells); + expjacterm.resize(num_cells); + cellA.resize(num_cells*nc*np); + faceA.resize(num_faces*nc*np); + phasemobf.resize(np*num_faces); + phasemobc.resize(num_cells); + phasemobf_deriv.resize(np*np*num_faces); + phasemobc_deriv.resize(np*np*num_cells); + gravcapf.resize(np*num_faces); + BOOST_STATIC_ASSERT(np == 3); + + // Compute and copy properties. + ManyFluidStatesBlackoil state; + fluid.computeManyStates(cell_pressure, cell_z, state); + totcompr = state.total_compressibility_; + totphasevol_density = state.total_phase_volume_density_; + saturation = state.saturation_; + rel_perm = state.relperm_; + viscosity = state.viscosity_; + phasemobc = state.mobility_; + phasemobc_deriv = state.dmobility_; + std::copy(&state.phase_to_comp_[0][0][0], + &state.phase_to_comp_[0][0][0] + num_cells*nc*np, + &cellA[0]); + expjacterm = state.experimental_term_; + +#pragma omp parallel for + for (int cell = 0; cell < num_cells; ++cell) { + double pv = rock.porosity(cell)*grid.cellVolume(cell); + voldiscr[cell] = (totphasevol_density[cell] - 1.0)*pv/dt; + relvoldiscr[cell] = std::fabs(totphasevol_density[cell] - 1.0); + + // Fractional flow must be calculated. + double total_mobility = 0.0; + for (int phase = 0; phase < numPhases; ++phase) { + total_mobility += state.mobility_[cell][phase]; + } + frac_flow[cell] = state.mobility_[cell]; + frac_flow[cell] /= total_mobility; + } + + // Obtain properties from both sides of the face. +#pragma omp parallel for + for (int face = 0; face < num_faces; ++face) { + typedef typename Grid::Vector Vec; + Vec fc = grid.faceCentroid(face); + int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; + + // Get pressures and compute gravity contributions, + // to decide upwind directions. + PhaseVec phase_p[2]; + PhaseVec gravcontrib[2]; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + // Pressures + phase_p[j] = cell_pressure[c[j]]; + // Gravity contribution. + if (nonzero_gravity) { + Vec cdiff = fc; + cdiff -= grid.cellCentroid(c[j]); + gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; + gravcontrib[j] *= (cdiff*gravity); + } else { + gravcontrib[j] = 0.0; + } + } else { + // Pressures + phase_p[j] = face_pressure[face]; + // Gravity contribution. + gravcontrib[j] = 0.0; + } + } + + // Gravity contribution: + // gravcapf = rho_1*g*(z_12 - z_1) - rho_2*g*(z_12 - z_2) + // where _1 and _2 refers to two neigbour cells, z is the + // z coordinate of the centroid, and z_12 is the face centroid. + // Also compute the potentials. + PhaseVec pot[2]; + for (int phase = 0; phase < np; ++phase) { + gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; + pot[1][phase] = phase_p[1][phase]; + } + + // Now we can easily find the upwind direction for every phase, + // we can also tell which boundary faces are inflow bdys. + + // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. + // Get mobilities and derivatives. + CompVec face_z(0.0); + double face_z_factor = 0.5; + PhaseVec phase_mob[2]; + PhaseJacobian phasemob_deriv[2]; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + face_z += cell_z[c[j]]; + phase_mob[j] = phasemobc[c[j]]; + phasemob_deriv[j] = phasemobc_deriv[c[j]]; + } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { + // Inflow boundary. + face_z += bdy_z; + FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); + phase_mob[j] = bdy_state.mobility_; + phasemob_deriv[j] = bdy_state.dmobility_; + } else { + // For outflow or noflow boundaries, only cell z is used. + face_z_factor = 1.0; + // Also, make sure the boundary data are not used for mobilities. + pot[j] = -1e100; + } + } + face_z *= face_z_factor; + + // Computing upwind mobilities and derivatives + for (int phase = 0; phase < np; ++phase) { + if (pot[0][phase] == pot[1][phase]) { + // Average. + double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); + phasemobf[np*face + phase] = aver; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] + + phasemob_deriv[1][phase][p2]; + } + } else { + // Upwind. + int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; + phasemobf[np*face + phase] = phase_mob[upwind][phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; + } + } + } + + // Find faceA. + FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); + std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); + } + } + + }; From 211bb7df8a93fdcd69a1f95fd291318b862d353a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 14:09:56 +0200 Subject: [PATCH 083/113] Ensured that no virtual functions are called in inner loops. --- .../blackoil/fluid/MiscibilityLiveOil.cpp | 82 ++++++++++++++----- .../blackoil/fluid/MiscibilityLiveOil.hpp | 5 ++ 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 6f5cc930..274df4da 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -190,17 +190,7 @@ namespace Opm // Dissolved gas-oil ratio double MiscibilityLiveOil::R(int /*region*/, double press, const surfvol_t& surfvol) const { - if (surfvol[Vapour] == 0.0) { - return 0.0; - } - double R = linearInterpolationExtrap(saturated_oil_table_[0], - saturated_oil_table_[3], press); - double maxR = surfvol[Vapour]/surfvol[Liquid]; - if (R < maxR ) { // Saturated case - return R; - } else { - return maxR; // Undersaturated case - } + return evalR(press, surfvol); } void MiscibilityLiveOil::R(const std::vector& pressures, @@ -212,7 +202,7 @@ namespace Opm int num = pressures.size(); output.resize(num); for (int i = 0; i < num; ++i) { - output[i] = R(0, pressures[i][phase], surfvol[i]); + output[i] = evalR(pressures[i][phase], surfvol[i]); } } @@ -238,18 +228,17 @@ namespace Opm std::vector& output_dRdp) const { ASSERT(pressures.size() == surfvol.size()); - R(pressures, surfvol, phase, output_R); int num = pressures.size(); + output_R.resize(num); output_dRdp.resize(num); for (int i = 0; i < num; ++i) { - output_dRdp[i] = dRdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated R. + evalRDeriv(pressures[i][phase], surfvol[i], output_R[i], output_dRdp[i]); } } double MiscibilityLiveOil::B(int /*region*/, double press, const surfvol_t& surfvol) const { - // if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. - return 1.0/miscible_oil(press, surfvol, 1, false); + return evalB(press, surfvol); } void MiscibilityLiveOil::B(const std::vector& pressures, @@ -261,14 +250,14 @@ namespace Opm int num = pressures.size(); output.resize(num); for (int i = 0; i < num; ++i) { - output[i] = B(0, pressures[i][phase], surfvol[i]); + output[i] = evalB(pressures[i][phase], surfvol[i]); } } - double MiscibilityLiveOil::dBdp(int region, double press, const surfvol_t& surfvol) const + double MiscibilityLiveOil::dBdp(int /*region*/, double press, const surfvol_t& surfvol) const { // if (surfvol[Liquid] == 0.0) return 0.0; // To handle no-oil case. - double Bo = B(region, press, surfvol); // \TODO check if we incur virtual call overhead here. + double Bo = evalB(press, surfvol); // \TODO check if we incur virtual call overhead here. return -Bo*Bo*miscible_oil(press, surfvol, 1, true); } @@ -287,6 +276,61 @@ namespace Opm } } + + double MiscibilityLiveOil::evalR(double press, const surfvol_t& surfvol) const + { + if (surfvol[Vapour] == 0.0) { + return 0.0; + } + double R = linearInterpolationExtrap(saturated_oil_table_[0], + saturated_oil_table_[3], press); + double maxR = surfvol[Vapour]/surfvol[Liquid]; + if (R < maxR ) { // Saturated case + return R; + } else { + return maxR; // Undersaturated case + } + } + + void MiscibilityLiveOil::evalRDeriv(const double press, const surfvol_t& surfvol, + double& R, double& dRdp) const + { + if (surfvol[Vapour] == 0.0) { + R = 0.0; + dRdp = 0.0; + return; + } + R = linearInterpolationExtrap(saturated_oil_table_[0], + saturated_oil_table_[3], press); + double maxR = surfvol[Vapour]/surfvol[Liquid]; + if (R < maxR ) { + // Saturated case + dRdp = linearInterpolDerivative(saturated_oil_table_[0], + saturated_oil_table_[3], + press); + } else { + // Undersaturated case + R = maxR; + dRdp = 0.0; + } + } + + + double MiscibilityLiveOil::evalB(double press, const surfvol_t& surfvol) const + { + // if (surfvol[Liquid] == 0.0) return 1.0; // To handle no-oil case. + return 1.0/miscible_oil(press, surfvol, 1, false); + } + + + void MiscibilityLiveOil::evalBDeriv(const double press, const surfvol_t& surfvol, + double& B, double& dBdp) const + { + B = evalB(press, surfvol); + dBdp = -B*B*miscible_oil(press, surfvol, 1, true); + } + + double MiscibilityLiveOil::miscible_oil(double press, const surfvol_t& surfvol, int item, bool deriv) const { diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp index 103012f1..6fd8ea42 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp @@ -77,6 +77,11 @@ namespace Opm std::vector& output_dRdp) const; protected: + double evalR(double press, const surfvol_t& surfvol) const; + void evalRDeriv(double press, const surfvol_t& surfvol, double& R, double& dRdp) const; + double evalB(double press, const surfvol_t& surfvol) const; + void evalBDeriv(double press, const surfvol_t& surfvol, double& B, double& dBdp) const; + // item: 1=B 2=mu; double miscible_oil(double press, const surfvol_t& surfvol, int item, bool deriv = false) const; From 80b268ae1a2986890c788259650fc68b782a37c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 20 Jun 2011 15:15:48 +0200 Subject: [PATCH 084/113] Added OpenMP pragmas to inner loops (not yet in MiscibilityLiveGas). --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 1 + dune/porsol/blackoil/fluid/MiscibilityDead.cpp | 3 +++ dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp | 5 +++++ dune/porsol/blackoil/fluid/MiscibilityWater.hpp | 2 ++ 4 files changed, 11 insertions(+) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index dcc6e218..b5ff1255 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -259,6 +259,7 @@ public: fluid_state.phase_compressibility_.resize(num); fluid_state.total_compressibility_.resize(num); fluid_state.experimental_term_.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { // Convenience vars. const PhaseVec& B = Bv[i]; diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp index 5a4aa6c2..c92b2abf 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityDead.cpp @@ -94,6 +94,7 @@ namespace Opm { int num = pressures.size(); output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output[i] = viscosity_(pressures[i][phase]); } @@ -112,6 +113,7 @@ namespace Opm { int num = pressures.size(); output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output[i] = 1.0/one_over_B_(pressures[i][phase]); } @@ -134,6 +136,7 @@ namespace Opm B(pressures, surfvols, phase, output_B); int num = pressures.size(); output_dBdp.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { double Bg = output_B[i]; output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(pressures[i][phase]); diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp index 274df4da..4b9fbe33 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp +++ b/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp @@ -182,6 +182,7 @@ namespace Opm ASSERT(pressures.size() == surfvol.size()); int num = pressures.size(); output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output[i] = miscible_oil(pressures[i][phase], surfvol[i], 2, false); } @@ -201,6 +202,7 @@ namespace Opm ASSERT(pressures.size() == surfvol.size()); int num = pressures.size(); output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output[i] = evalR(pressures[i][phase], surfvol[i]); } @@ -231,6 +233,7 @@ namespace Opm int num = pressures.size(); output_R.resize(num); output_dRdp.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { evalRDeriv(pressures[i][phase], surfvol[i], output_R[i], output_dRdp[i]); } @@ -249,6 +252,7 @@ namespace Opm ASSERT(pressures.size() == surfvol.size()); int num = pressures.size(); output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output[i] = evalB(pressures[i][phase], surfvol[i]); } @@ -271,6 +275,7 @@ namespace Opm B(pressures, surfvol, phase, output_B); int num = pressures.size(); output_dBdp.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output_dBdp[i] = dBdp(0, pressures[i][phase], surfvol[i]); // \TODO Speedup here by using already evaluated B. } diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp index 5553ada5..2082daa0 100644 --- a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp +++ b/dune/porsol/blackoil/fluid/MiscibilityWater.hpp @@ -108,6 +108,7 @@ namespace Opm int num = pressures.size(); if (comp_) { output.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { // Computing a polynomial approximation to the exponential. double x = comp_*(pressures[i][phase] - ref_press_); @@ -138,6 +139,7 @@ namespace Opm int num = pressures.size(); if (comp_) { output_dBdp.resize(num); +#pragma omp parallel for for (int i = 0; i < num; ++i) { output_dBdp[i] = -comp_*output_B[i]; } From bccb052c08b698bc8b5647665b5f2bc6d6c360b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 22 Jun 2011 10:47:33 +0200 Subject: [PATCH 085/113] Using FieldMatrix<> now, initial nonworking version. --- .../blackoil/fluid/FluidSystemBlackoil.hpp | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index b5ff1255..ca567f2f 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -36,7 +36,7 @@ #include "BlackoilPVT.hpp" #include "BlackoilDefs.hpp" -#include +//#include #include #include @@ -151,6 +151,7 @@ public: template static void computeEquilibrium(FluidState& fluid_state) { +#if 0 // Get B and R factors. const PhaseVec& p = fluid_state.phase_pressure_; const CompVec& z = fluid_state.surface_volume_; @@ -227,6 +228,7 @@ public: // Experimental term. PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; +#endif } /*! @@ -269,13 +271,24 @@ public: const CompVec& z = zv[i]; // Set the A matrix (A = RB^{-1}) - Dune::SharedFortranMatrix A(numComponents, numPhases, &fluid_state.phase_to_comp_[i][0][0]); + // Using At since we really want Fortran ordering + // (since ultimately that is what the opmpressure + // C library expects). + PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; + /* zero(A); A(Water, Aqua) = 1.0/B[Aqua]; A(Gas, Vapour) = 1.0/B[Vapour]; A(Gas, Liquid) = R[Liquid]/B[Liquid]; A(Oil, Vapour) = R[Vapour]/B[Vapour]; A(Oil, Liquid) = 1.0/B[Liquid]; + */ + At = 0.0; + At[Aqua][Water] = 1.0/B[Aqua]; + At[Vapour][Gas] = 1.0/B[Vapour]; + At[Liquid][Gas] = R[Liquid]/B[Liquid]; + At[Vapour][Oil] = R[Vapour]/B[Vapour]; + At[Liquid][Oil] = 1.0/B[Liquid]; // Update phase volumes. This is the same as multiplying with A^{-1} PhaseVec& u = fluid_state.phase_volume_density_[i]; @@ -295,6 +308,7 @@ public: // Phase compressibilities. PhaseVec& cp = fluid_state.phase_compressibility_[i]; // Set the derivative of the A matrix (A = RB^{-1}) + /* double data_for_dA[numComponents*numPhases]; Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); zero(dA); @@ -303,24 +317,51 @@ public: dA(Oil, Liquid) = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. dA(Gas, Liquid) = dA(Oil, Liquid)*R[Liquid] + dR[Liquid]/B[Liquid]; dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; + */ + PhaseToCompMatrix dAt(0.0); + dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); + dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); + dAt[Liquid][Oil] = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. + dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; + dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; + + /* double data_for_Ai[numComponents*numPhases]; Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); - // Ai = A; // This does not make a deep copy. std::copy(A.data(), A.data() + numComponents*numPhases, Ai.data()); Dune::invert(Ai); + */ + PhaseToCompMatrix Ait; + Dune::FMatrixHelp::invertMatrix(At, Ait); + + /* double data_for_C[numComponents*numPhases]; Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); Dune::prod(Ai, dA, C); - //CompVec ones(1.0); - //cp = Dune::prod(C, ones); // Probably C' and not C; we want phasewise compressibilities: + */ + PhaseToCompMatrix Ct; + Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); + + /* cp[Aqua] = C(Water, Aqua); cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); + */ + cp[Aqua] = Ct[Aqua][Water]; + cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; + cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; fluid_state.total_compressibility_[i] = cp*s; // Experimental term. + /* PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); fluid_state.experimental_term_[i] = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; + */ + PhaseVec tmp1, tmp2, tmp3; + Ait.mtv(z, tmp1); + dAt.mtv(tmp1, tmp2); + Ait.mtv(tmp2, tmp3); + fluid_state.experimental_term_[i] = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; } } From 6b8fabc7bcb64f28cdd0760cac8eec90dd95be55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 22 Jun 2011 11:08:04 +0200 Subject: [PATCH 086/113] Reinstate old code that was erroneously #if'ed out. --- dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index ca567f2f..bf40bfce 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -36,7 +36,7 @@ #include "BlackoilPVT.hpp" #include "BlackoilDefs.hpp" -//#include +#include #include #include @@ -151,7 +151,6 @@ public: template static void computeEquilibrium(FluidState& fluid_state) { -#if 0 // Get B and R factors. const PhaseVec& p = fluid_state.phase_pressure_; const CompVec& z = fluid_state.surface_volume_; @@ -228,7 +227,6 @@ public: // Experimental term. PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; -#endif } /*! From 9740519e602410a33a674270bc2e06a0ad7ef598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 22 Jun 2011 13:53:19 +0200 Subject: [PATCH 087/113] Now computeEquilibrium() calls computeSingleEquilibrium(). Minor fixes. --- .../blackoil/fluid/FluidSystemBlackoil.hpp | 164 +++++++++++++----- 1 file changed, 119 insertions(+), 45 deletions(-) diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp index bf40bfce..89d95395 100644 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp @@ -159,8 +159,38 @@ public: B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); PhaseVec& R = fluid_state.solution_factor_; + R[Aqua] = 0.0; R[Vapour] = params().pvt_.R(p[Vapour], z, Vapour); R[Liquid] = params().pvt_.R(p[Liquid], z, Liquid); + PhaseVec dB; + dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); + dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); + dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); + PhaseVec dR; + dR[Aqua] = 0.0; + dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); + dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); + + // Convenience vars. + PhaseToCompMatrix& At = fluid_state.phase_to_comp_; + PhaseVec& u = fluid_state.phase_volume_density_; + double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_; + PhaseVec& s = fluid_state.saturation_; + PhaseVec& cp = fluid_state.phase_compressibility_; + double& tot_comp = fluid_state.total_compressibility_; + double& exp_term = fluid_state.experimental_term_; + + computeSingleEquilibrium(B, dB, R, dR, z, + At, u, tot_phase_vol_dens, + s, cp, tot_comp, exp_term); + + // Compute viscosities. + PhaseVec& mu = fluid_state.viscosity_; + mu[Aqua] = params().pvt_.getViscosity(p[Aqua], z, Aqua); + mu[Vapour] = params().pvt_.getViscosity(p[Vapour], z, Vapour); + mu[Liquid] = params().pvt_.getViscosity(p[Liquid], z, Liquid); + + /* // Set the A matrix (A = RB^{-1}) Dune::SharedFortranMatrix A(numComponents, numPhases, &fluid_state.phase_to_comp_[0][0]); zero(A); @@ -193,13 +223,13 @@ public: // Phase compressibilities. PhaseVec& cp = fluid_state.phase_compressibility_; - double dB[3]; - dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); - dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); - dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); - double dR[3]; // Only using 2 of them, though. - dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); - dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); +// double dB[3]; +// dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); +// dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); +// dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); +// double dR[3]; // Only using 2 of them, though. +// dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); +// dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); // Set the derivative of the A matrix (A = RB^{-1}) double data_for_dA[numComponents*numPhases]; Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); @@ -227,6 +257,75 @@ public: // Experimental term. PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; + */ + } + + + static void computeSingleEquilibrium(const PhaseVec& B, + const PhaseVec& dB, + const PhaseVec& R, + const PhaseVec& dR, + const CompVec& z, + PhaseToCompMatrix& At, + PhaseVec& u, + double& tot_phase_vol_dens, + PhaseVec& s, + PhaseVec& cp, + double& tot_comp, + double& exp_term) + { + // Set the A matrix (A = RB^{-1}) + // Using At since we really want Fortran ordering + // (since ultimately that is what the opmpressure + // C library expects). + // PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; + At = 0.0; + At[Aqua][Water] = 1.0/B[Aqua]; + At[Vapour][Gas] = 1.0/B[Vapour]; + At[Liquid][Gas] = R[Liquid]/B[Liquid]; + At[Vapour][Oil] = R[Vapour]/B[Vapour]; + At[Liquid][Oil] = 1.0/B[Liquid]; + + // Update phase volumes. This is the same as multiplying with A^{-1} + // PhaseVec& u = fluid_state.phase_volume_density_[i]; + double detR = 1.0 - R[Vapour]*R[Liquid]; + u[Aqua] = B[Aqua]*z[Water]; + u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; + u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; + tot_phase_vol_dens = u[Aqua] + u[Vapour] + u[Liquid]; + + // PhaseVec& s = fluid_state.saturation_[i]; + for (int phase = 0; phase < numPhases; ++phase) { + s[phase] = u[phase]/tot_phase_vol_dens; + } + + // Phase compressibilities. + // PhaseVec& cp = fluid_state.phase_compressibility_[i]; + // Set the derivative of the A matrix (A = RB^{-1}) + PhaseToCompMatrix dAt(0.0); + dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); + dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); + dAt[Liquid][Oil] = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. + dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; + dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; + + PhaseToCompMatrix Ait; + Dune::FMatrixHelp::invertMatrix(At, Ait); + + PhaseToCompMatrix Ct; + Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); + + cp[Aqua] = Ct[Aqua][Water]; + cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; + cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; + tot_comp = cp*s; + + // Experimental term. + PhaseVec tmp1, tmp2, tmp3; + Ait.mtv(z, tmp1); + dAt.mtv(tmp1, tmp2); + Ait.mtv(tmp2, tmp3); + exp_term = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; } /*! @@ -268,19 +367,23 @@ public: const PhaseVec& dR = dRv[i]; const CompVec& z = zv[i]; + PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; + PhaseVec& u = fluid_state.phase_volume_density_[i]; + double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_[i]; + PhaseVec& s = fluid_state.saturation_[i]; + PhaseVec& cp = fluid_state.phase_compressibility_[i]; + double& tot_comp = fluid_state.total_compressibility_[i]; + double& exp_term = fluid_state.experimental_term_[i]; + + computeSingleEquilibrium(B, dB, R, dR, z, + At, u, tot_phase_vol_dens, + s, cp, tot_comp, exp_term); + /* // Set the A matrix (A = RB^{-1}) // Using At since we really want Fortran ordering // (since ultimately that is what the opmpressure // C library expects). PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; - /* - zero(A); - A(Water, Aqua) = 1.0/B[Aqua]; - A(Gas, Vapour) = 1.0/B[Vapour]; - A(Gas, Liquid) = R[Liquid]/B[Liquid]; - A(Oil, Vapour) = R[Vapour]/B[Vapour]; - A(Oil, Liquid) = 1.0/B[Liquid]; - */ At = 0.0; At[Aqua][Water] = 1.0/B[Aqua]; At[Vapour][Gas] = 1.0/B[Vapour]; @@ -306,16 +409,6 @@ public: // Phase compressibilities. PhaseVec& cp = fluid_state.phase_compressibility_[i]; // Set the derivative of the A matrix (A = RB^{-1}) - /* - double data_for_dA[numComponents*numPhases]; - Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); - zero(dA); - dA(Water, Aqua) = -dB[Aqua]/(B[Aqua]*B[Aqua]); - dA(Gas, Vapour) = -dB[Vapour]/(B[Vapour]*B[Vapour]); - dA(Oil, Liquid) = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. - dA(Gas, Liquid) = dA(Oil, Liquid)*R[Liquid] + dR[Liquid]/B[Liquid]; - dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; - */ PhaseToCompMatrix dAt(0.0); dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); @@ -323,43 +416,24 @@ public: dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; - /* - double data_for_Ai[numComponents*numPhases]; - Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); - std::copy(A.data(), A.data() + numComponents*numPhases, Ai.data()); - Dune::invert(Ai); - */ PhaseToCompMatrix Ait; Dune::FMatrixHelp::invertMatrix(At, Ait); - /* - double data_for_C[numComponents*numPhases]; - Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); - Dune::prod(Ai, dA, C); - */ PhaseToCompMatrix Ct; Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); - /* - cp[Aqua] = C(Water, Aqua); - cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); - cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); - */ cp[Aqua] = Ct[Aqua][Water]; cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; fluid_state.total_compressibility_[i] = cp*s; // Experimental term. - /* - PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); - fluid_state.experimental_term_[i] = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; - */ PhaseVec tmp1, tmp2, tmp3; Ait.mtv(z, tmp1); dAt.mtv(tmp1, tmp2); Ait.mtv(tmp2, tmp3); fluid_state.experimental_term_[i] = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; + */ } } From ade7520b9881f9eb7c29b08d956ce64017026091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Jun 2011 12:48:54 +0200 Subject: [PATCH 088/113] Added (unused) code collecting 'A' matrix construction for faces. --- dune/porsol/blackoil/BlackoilFluid.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 887f777c..73208708 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -388,9 +388,10 @@ namespace Opm frac_flow[cell] /= total_mobility; } - // Obtain properties from both sides of the face. + // std::vector face_z_vec(num_faces); #pragma omp parallel for for (int face = 0; face < num_faces; ++face) { + // Obtain properties from both sides of the face. typedef typename Grid::Vector Vec; Vec fc = grid.faceCentroid(face); int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; @@ -460,6 +461,7 @@ namespace Opm } } face_z *= face_z_factor; + // face_z_vec[face] = face_z; // Computing upwind mobilities and derivatives for (int phase = 0; phase < np; ++phase) { @@ -480,11 +482,16 @@ namespace Opm } } } - // Find faceA. FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); } + + // Find faceA. Slower, since it does too much. +// ManyFluidStatesBlackoil face_state; +// fluid.computeManyStates(face_pressure, face_z_vec, face_state); +// const double* fA = &face_state.phase_to_comp_[0][0][0]; +// std::copy(fA, fA + num_faces*nc*np, &faceA[0]); } From 70ad4a00cc5e310cb5750c7be2eb6c9cabee1088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Jun 2011 13:28:30 +0200 Subject: [PATCH 089/113] Moved equilibrium computations here from FluidSystemBlackoil --- dune/porsol/blackoil/BlackoilFluid.hpp | 190 ++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 4 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 73208708..8d2833d1 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -48,7 +48,8 @@ namespace Opm void init(const Dune::EclipseGridParser& parser) { fmi_params_.init(parser); - FluidSystemBlackoil<>::init(parser); + // FluidSystemBlackoil<>::init(parser); + pvt_.init(parser); const std::vector& dens = parser.getDENSITY().densities_[0]; surface_densities_[Oil] = dens[0]; surface_densities_[Water] = dens[1]; @@ -61,7 +62,8 @@ namespace Opm state.temperature_ = 300; state.phase_pressure_ = phase_pressure; state.surface_volume_ = z; - FluidSystemBlackoil<>::computeEquilibrium(state); // Sets everything but relperm and mobility. + // FluidSystemBlackoil<>::computeEquilibrium(state); // Sets everything but relperm and mobility. + computeEquilibrium(state); FluidMatrixInteractionBlackoil::kr(state.relperm_, fmi_params_, state.saturation_, state.temperature_); FluidMatrixInteractionBlackoil::dkr(state.drelperm_, fmi_params_, state.saturation_, state.temperature_); for (int phase = 0; phase < numPhases; ++phase) { @@ -83,7 +85,8 @@ namespace Opm state.temperature_.resize(num, 300.0); state.phase_pressure_ = phase_pressure; state.surface_volume_ = z; - FluidSystemBlackoil<>::computeManyEquilibria(state); // Sets everything but relperm and mobility. + // FluidSystemBlackoil<>::computeManyEquilibria(state); // Sets everything but relperm and mobility. + computeManyEquilibria(state); state.relperm_.resize(num); state.drelperm_.resize(num); state.mobility_.resize(num); @@ -104,6 +107,7 @@ namespace Opm } } + const CompVec& surfaceDensities() const { return surface_densities_; @@ -119,16 +123,194 @@ namespace Opm } } return phase_dens; - } + } private: + BlackoilPVT pvt_; FluidMatrixInteractionBlackoilParams fmi_params_; CompVec surface_densities_; + + + /*! + * \brief Assuming the surface volumes and the pressures of all + * phases are known, compute everything except relperm and + * mobility. + */ + template + void computeEquilibrium(FluidState& fluid_state) const + { + // Get B and R factors. + const PhaseVec& p = fluid_state.phase_pressure_; + const CompVec& z = fluid_state.surface_volume_; + PhaseVec& B = fluid_state.formation_volume_factor_; + B[Aqua] = pvt_.B(p[Aqua], z, Aqua); + B[Vapour] = pvt_.B(p[Vapour], z, Vapour); + B[Liquid] = pvt_.B(p[Liquid], z, Liquid); + PhaseVec& R = fluid_state.solution_factor_; + R[Aqua] = 0.0; + R[Vapour] = pvt_.R(p[Vapour], z, Vapour); + R[Liquid] = pvt_.R(p[Liquid], z, Liquid); + PhaseVec dB; + dB[Aqua] = pvt_.dBdp(p[Aqua], z, Aqua); + dB[Vapour] = pvt_.dBdp(p[Vapour], z, Vapour); + dB[Liquid] = pvt_.dBdp(p[Liquid], z, Liquid); + PhaseVec dR; + dR[Aqua] = 0.0; + dR[Vapour] = pvt_.dRdp(p[Vapour], z, Vapour); + dR[Liquid] = pvt_.dRdp(p[Liquid], z, Liquid); + + // Convenience vars. + PhaseToCompMatrix& At = fluid_state.phase_to_comp_; + PhaseVec& u = fluid_state.phase_volume_density_; + double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_; + PhaseVec& s = fluid_state.saturation_; + PhaseVec& cp = fluid_state.phase_compressibility_; + double& tot_comp = fluid_state.total_compressibility_; + double& exp_term = fluid_state.experimental_term_; + + computeSingleEquilibrium(B, dB, R, dR, z, + At, u, tot_phase_vol_dens, + s, cp, tot_comp, exp_term); + + // Compute viscosities. + PhaseVec& mu = fluid_state.viscosity_; + mu[Aqua] = pvt_.getViscosity(p[Aqua], z, Aqua); + mu[Vapour] = pvt_.getViscosity(p[Vapour], z, Vapour); + mu[Liquid] = pvt_.getViscosity(p[Liquid], z, Liquid); + } + + /*! + * \brief Assuming the surface volumes and the pressures of all + * phases are known, compute everything except relperm and + * mobility. + */ + template + void computeManyEquilibria(ManyFluidStates& fluid_state) const + { + // Get B and R factors, viscosities. Vectorized at lower level. + const std::vector& pv = fluid_state.phase_pressure_; + const std::vector& zv = fluid_state.surface_volume_; + std::vector& Bv = fluid_state.formation_volume_factor_; + std::vector dBv; + pvt_.dBdp(pv, zv, Bv, dBv); + std::vector& Rv = fluid_state.solution_factor_; + std::vector dRv; + pvt_.dRdp(pv, zv, Rv, dRv); + std::vector& muv = fluid_state.viscosity_; + pvt_.getViscosity(pv, zv, muv); + + // The rest is vectorized in this function. + int num = pv.size(); + fluid_state.phase_to_comp_.resize(num); + fluid_state.phase_volume_density_.resize(num); + fluid_state.total_phase_volume_density_.resize(num); + fluid_state.phase_to_comp_.resize(num); + fluid_state.saturation_.resize(num); + fluid_state.phase_compressibility_.resize(num); + fluid_state.total_compressibility_.resize(num); + fluid_state.experimental_term_.resize(num); +#pragma omp parallel for + for (int i = 0; i < num; ++i) { + // Convenience vars. + const PhaseVec& B = Bv[i]; + const PhaseVec& dB = dBv[i]; + const PhaseVec& R = Rv[i]; + const PhaseVec& dR = dRv[i]; + const CompVec& z = zv[i]; + + PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; + PhaseVec& u = fluid_state.phase_volume_density_[i]; + double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_[i]; + PhaseVec& s = fluid_state.saturation_[i]; + PhaseVec& cp = fluid_state.phase_compressibility_[i]; + double& tot_comp = fluid_state.total_compressibility_[i]; + double& exp_term = fluid_state.experimental_term_[i]; + + computeSingleEquilibrium(B, dB, R, dR, z, + At, u, tot_phase_vol_dens, + s, cp, tot_comp, exp_term); + } + } + + static void computeSingleEquilibrium(const PhaseVec& B, + const PhaseVec& dB, + const PhaseVec& R, + const PhaseVec& dR, + const CompVec& z, + PhaseToCompMatrix& At, + PhaseVec& u, + double& tot_phase_vol_dens, + PhaseVec& s, + PhaseVec& cp, + double& tot_comp, + double& exp_term) + { + // Set the A matrix (A = RB^{-1}) + // Using At since we really want Fortran ordering + // (since ultimately that is what the opmpressure + // C library expects). + // PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; + At = 0.0; + At[Aqua][Water] = 1.0/B[Aqua]; + At[Vapour][Gas] = 1.0/B[Vapour]; + At[Liquid][Gas] = R[Liquid]/B[Liquid]; + At[Vapour][Oil] = R[Vapour]/B[Vapour]; + At[Liquid][Oil] = 1.0/B[Liquid]; + + // Update phase volumes. This is the same as multiplying with A^{-1} + // PhaseVec& u = fluid_state.phase_volume_density_[i]; + double detR = 1.0 - R[Vapour]*R[Liquid]; + u[Aqua] = B[Aqua]*z[Water]; + u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; + u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; + tot_phase_vol_dens = u[Aqua] + u[Vapour] + u[Liquid]; + + // PhaseVec& s = fluid_state.saturation_[i]; + for (int phase = 0; phase < numPhases; ++phase) { + s[phase] = u[phase]/tot_phase_vol_dens; + } + + // Phase compressibilities. + // PhaseVec& cp = fluid_state.phase_compressibility_[i]; + // Set the derivative of the A matrix (A = RB^{-1}) + PhaseToCompMatrix dAt(0.0); + dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); + dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); + dAt[Liquid][Oil] = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. + dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; + dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; + + PhaseToCompMatrix Ait; + Dune::FMatrixHelp::invertMatrix(At, Ait); + + PhaseToCompMatrix Ct; + Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); + + cp[Aqua] = Ct[Aqua][Water]; + cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; + cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; + tot_comp = cp*s; + + // Experimental term. + PhaseVec tmp1, tmp2, tmp3; + Ait.mtv(z, tmp1); + dAt.mtv(tmp1, tmp2); + Ait.mtv(tmp2, tmp3); + exp_term = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; + } + + }; + + + + + + /// Container for all fluid data needed by solvers. struct BlackoilFluidData : public BlackoilDefs { From f7a9cef1292d79e30e55ad5cef9fdacc701cbd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Sun, 26 Jun 2011 13:08:08 +0200 Subject: [PATCH 090/113] Added AllFluidStates struct. --- .../blackoil/fluid/FluidStateBlackoil.hpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 9c539664..1dcbcb99 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -74,6 +74,40 @@ namespace Opm std::vector dmobility_; }; + /*! + * \brief Multiple fluid states for a black oil model. + */ + struct AllFluidStates : public BlackoilDefs + { + // Canonical state variables. + std::vector surface_volume_density; // z + std::vector phase_pressure; // p + + // Variables from PVT functions. + std::vector formation_volume_factor; // B + std::vector formation_volume_factor_deriv; // dB/dp + std::vector solution_factor; // R + std::vector solution_factor_deriv; // dR/dp + std::vector viscosity; // mu + + // Variables computed from PVT data. + // The A matrices are all in Fortran order (or, equivalently, + // we store the transposes). + std::vector state_matrix; // A' = (RB^{-1})' + std::vector phase_volume_density; // u + std::vector total_phase_volume_density; // sum(u) + std::vector saturation; // s = u/sum(u) + std::vector phase_compressibility; // c + std::vector total_compressibility; // cT + std::vector experimental_term; // ex = sum(Ai*dA*Ai*z) + + // Variables computed from saturation. + std::vector relperm; // kr + std::vector relperm_deriv; // dkr/ds + std::vector mobility; // lambda + std::vector mobility_deriv; // dlambda/ds + }; + } // end namespace Opm From bdcc06782a36650aa1fa77429d7bb2312aa6a649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Sun, 26 Jun 2011 13:10:18 +0200 Subject: [PATCH 091/113] Added more fine-grained set of methods to BlackoilFluid class. --- dune/porsol/blackoil/BlackoilFluid.hpp | 171 ++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 2 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 8d2833d1..b16777d0 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -125,6 +125,163 @@ namespace Opm return phase_dens; } + + // ---- New interface ---- + + /// Input: p, z + /// Output: B, R + template + void computeBAndR(States& states) + { + const std::vector& p = states.phase_pressure; + const std::vector& z = states.surface_volume_density; + std::vector& B = states.formation_volume_factor; + std::vector& R = states.solution_factor; + pvt_.B(p, z, B); + pvt_.R(p, z, R); + } + + /// Input: p, z + /// Output: B, R, mu + template + void computePvtNoDerivs(States& states) + { + computeBAndR(states); + const std::vector& p = states.phase_pressure; + const std::vector& z = states.surface_volume_density; + std::vector& mu = states.viscosity; + pvt_.getViscosity(p, z, mu); + } + + /// Input: p, z + /// Output: B, dB/dp, R, dR/dp, mu + template + void computePvt(States& states) + { + const std::vector& p = states.phase_pressure; + const std::vector& z = states.surface_volume_density; + std::vector& B = states.formation_volume_factor; + std::vector& dB = states.formation_volume_factor_deriv; + std::vector& R = states.solution_factor; + std::vector& dR = states.solution_factor_deriv; + std::vector& mu = states.viscosity; + pvt_.dBdp(p, z, B, dB); + pvt_.dRdp(p, z, R, dR); + pvt_.getViscosity(p, z, mu); + } + + /// Input: B, R + /// Output: A + template + void computeStateMatrix(States& states) + { + int num = states.state_matrix.size(); + states.state_matrix.resize(num); +#pragma omp parallel for + for (int i = 0; i < num; ++i) { + const PhaseVec& B = states.formation_volume_factor[i]; + const PhaseVec& R = states.solution_factor[i]; + PhaseToCompMatrix& At = states.state_matrix[i]; + // Set the A matrix (A = RB^{-1}) + // Using A transposed (At) since we really want Fortran ordering: + // ultimately that is what the opmpressure C library expects. + At = 0.0; + At[Aqua][Water] = 1.0/B[Aqua]; + At[Vapour][Gas] = 1.0/B[Vapour]; + At[Liquid][Gas] = R[Liquid]/B[Liquid]; + At[Vapour][Oil] = R[Vapour]/B[Vapour]; + At[Liquid][Oil] = 1.0/B[Liquid]; + } + } + + + /// Input: z, B, dB/dp, R, dR/dp + /// Output: A, u, sum(u), s, c, cT, ex + template + void computePvtDepending(States& states) + { + int num = states.state_matrix.size(); + states.state_matrix.resize(num); + states.phase_volume_density.resize(num); + states.total_phase_volume_density.resize(num); + states.saturation.resize(num); + states.phase_compressibility.resize(num); + states.total_compressibility.resize(num); + states.experimental_term.resize(num); +#pragma omp parallel for + for (int i = 0; i < num; ++i) { + const CompVec& z = states.surface_volume_density[i]; + const PhaseVec& B = states.formation_volume_factor[i]; + const PhaseVec& dB = states.formation_volume_factor_deriv[i]; + const PhaseVec& R = states.solution_factor[i]; + const PhaseVec& dR = states.solution_factor_deriv[i]; + PhaseToCompMatrix& At = states.state_matrix[i]; + PhaseVec& u = states.phase_volume_density[i]; + double& tot_phase_vol_dens = states.total_phase_volume_density[i]; + PhaseVec& s = states.saturation[i]; + PhaseVec& cp = states.phase_compressibility[i]; + double& tot_comp = states.total_compressibility[i]; + double& exp_term = states.experimental_term[i]; + computeSingleEquilibrium(B, dB, R, dR, z, + At, u, tot_phase_vol_dens, + s, cp, tot_comp, exp_term); + } + } + + /// Input: s, mu + /// Output: kr, lambda + template + void computeMobilitiesNoDerivs(States& states) + { + int num = states.state_matrix.size(); + states.relperm.resize(num); + states.mobility.resize(num); +#pragma omp parallel for + for (int i = 0; i < num; ++i) { + const CompVec& s = states.saturation[i]; + const PhaseVec& mu = states.viscosity[i]; + PhaseVec& kr = states.relperm[i]; + PhaseVec& lambda = states.mobility[i]; + FluidMatrixInteractionBlackoil::kr(kr, fmi_params_, s, 300.0); + for (int phase = 0; phase < numPhases; ++phase) { + lambda[phase] = kr[phase]/mu[phase]; + } + + } + } + + /// Input: s, mu + /// Output: kr, dkr/ds, lambda, dlambda/ds + template + void computeMobilities(States& states) + { + int num = states.state_matrix.size(); + states.relperm.resize(num); + states.relperm_deriv.resize(num); + states.mobility.resize(num); + states.mobility_deriv.resize(num); +#pragma omp parallel for + for (int i = 0; i < num; ++i) { + const CompVec& s = states.saturation[i]; + const PhaseVec& mu = states.viscosity[i]; + PhaseVec& kr = states.relperm[i]; + PhaseJacobian& dkr = states.relperm_deriv[i]; + PhaseVec& lambda = states.mobility[i]; + PhaseJacobian& dlambda = states.mobility_deriv[i]; + FluidMatrixInteractionBlackoil::kr(kr, fmi_params_, s, 300.0); + FluidMatrixInteractionBlackoil::dkr(dkr, fmi_params_, s, 300.0); + for (int phase = 0; phase < numPhases; ++phase) { + lambda[phase] = kr[phase]/mu[phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + // Ignoring pressure variation in viscosity for this one. + dlambda[phase][p2] = dkr[phase][p2]/mu[phase]; + } + } + + } + } + + private: BlackoilPVT pvt_; FluidMatrixInteractionBlackoilParams fmi_params_; @@ -306,9 +463,19 @@ namespace Opm + struct AllFluidData : public BlackoilDefs + { + // Per-cell data + AllFluidStates cell_data; - - + // Per-face data. + std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. + std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). + std::vector phasemobc; // Phase mobilities per cell. + std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). + std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. + std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. + }; /// Container for all fluid data needed by solvers. From 72388ad717c2ca17fe8160e77b0114159d890428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 28 Jun 2011 10:17:36 +0200 Subject: [PATCH 092/113] Added AllFluidData struct and its computeNew() method. --- dune/porsol/blackoil/BlackoilFluid.hpp | 170 ++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 6 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index b16777d0..1acb42ea 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -467,17 +467,175 @@ namespace Opm { // Per-cell data AllFluidStates cell_data; + std::vector voldiscr; + std::vector relvoldiscr; // Per-face data. - std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. - std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). - std::vector phasemobc; // Phase mobilities per cell. - std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). - std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. - std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. + std::vector faceA; // A = RB^{-1}. Fortran ordering. + std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). + std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). + std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. + + public: + template + void computeNew(const Grid& grid, + const Rock& rock, + const BlackoilFluid& fluid, + const typename Grid::Vector gravity, + const std::vector& cell_pressure, + const std::vector& face_pressure, + const std::vector& cell_z, + const CompVec& bdy_z, + const double dt) + { + int num_cells = cell_z.size(); + ASSERT(num_cells == grid.numCells()); + int num_faces = face_pressure.size(); + ASSERT(num_faces == grid.numFaces()); + const int np = numPhases; + const int nc = numComponents; + bool nonzero_gravity = gravity.two_norm() > 0.0; + BOOST_STATIC_ASSERT(np == nc); + BOOST_STATIC_ASSERT(np == 3); + + // p, z -> B, dB, R, dR, mu, A, dA, u, sum(u), s, c, cT, ex, kr, dkr, lambda, dlambda. + cell_data.phase_pressure = cell_pressure; + cell_data.surface_volume_density = cell_z; + fluid.computePvt(cell_data); + fluid.computePvtDepending(cell_data); + fluid.computeMobilities(cell_data); + + // Compute volume discrepancies. + voldiscr.resize(num_cells); + relvoldiscr.resize(num_cells); +#pragma omp parallel for + for (int cell = 0; cell < num_cells; ++cell) { + double pv = rock.porosity(cell)*grid.cellVolume(cell); + voldiscr[cell] = (cell_data.total_phase_volume_density[cell] - 1.0)*pv/dt; + relvoldiscr[cell] = std::fabs(cell_data.total_phase_volume_density[cell] - 1.0); + } + + // Compute face properties. + faceA.resize(num_faces); + phasemobf.resize(num_faces); + phasemobf_deriv.resize(num_faces); + gravcapf.resize(num_faces); + // std::vector face_z_vec(num_faces); +#pragma omp parallel for + for (int face = 0; face < num_faces; ++face) { + // Obtain properties from both sides of the face. + typedef typename Grid::Vector Vec; + Vec fc = grid.faceCentroid(face); + int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; + + // Get pressures and compute gravity contributions, + // to decide upwind directions. + PhaseVec phase_p[2]; + PhaseVec gravcontrib[2]; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + // Pressures + phase_p[j] = cell_pressure[c[j]]; + // Gravity contribution. + if (nonzero_gravity) { + Vec cdiff = fc; + cdiff -= grid.cellCentroid(c[j]); + gravcontrib[j] = fluid.phaseDensities(&cell_data.state_matrix[c[j]][0][0]); + gravcontrib[j] *= (cdiff*gravity); + } else { + gravcontrib[j] = 0.0; + } + } else { + // Pressures + phase_p[j] = face_pressure[face]; + // Gravity contribution. + gravcontrib[j] = 0.0; + } + } + + // Gravity contribution: + // gravcapf = rho_1*g*(z_12 - z_1) - rho_2*g*(z_12 - z_2) + // where _1 and _2 refers to two neigbour cells, z is the + // z coordinate of the centroid, and z_12 is the face centroid. + // Also compute the potentials. + PhaseVec pot[2]; + for (int phase = 0; phase < np; ++phase) { + gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + pot[0][phase] = phase_p[0][phase] + gravcapf[face][phase]; + pot[1][phase] = phase_p[1][phase]; + } + + // Now we can easily find the upwind direction for every phase, + // we can also tell which boundary faces are inflow bdys. + + // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. + // Get mobilities and derivatives. + CompVec face_z(0.0); + double face_z_factor = 0.5; + PhaseVec phase_mob[2]; + PhaseJacobian phasemob_deriv[2]; + for (int j = 0; j < 2; ++j) { + if (c[j] >= 0) { + face_z += cell_z[c[j]]; + phase_mob[j] = cell_data.mobility[c[j]]; + phasemob_deriv[j] = cell_data.mobility_deriv[c[j]]; + } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { + // Inflow boundary. + face_z += bdy_z; + FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); + phase_mob[j] = bdy_state.mobility_; + phasemob_deriv[j] = bdy_state.dmobility_; + } else { + // For outflow or noflow boundaries, only cell z is used. + face_z_factor = 1.0; + // Also, make sure the boundary data are not used for mobilities. + pot[j] = -1e100; + } + } + face_z *= face_z_factor; + // face_z_vec[face] = face_z; + + // Computing upwind mobilities and derivatives + for (int phase = 0; phase < np; ++phase) { + if (pot[0][phase] == pot[1][phase]) { + // Average. + double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); + phasemobf[np*face + phase] = aver; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] + + phasemob_deriv[1][phase][p2]; + } + } else { + // Upwind. + int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; + phasemobf[np*face + phase] = phase_mob[upwind][phase]; + for (int p2 = 0; p2 < numPhases; ++p2) { + phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; + } + } + } + // Find faceA. + FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); + std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); + } + + // Find faceA. Slower, since it does too much. +// ManyFluidStatesBlackoil face_state; +// fluid.computeManyStates(face_pressure, face_z_vec, face_state); +// const double* fA = &face_state.phase_to_comp_[0][0][0]; +// std::copy(fA, fA + num_faces*nc*np, &faceA[0]); + } + + }; + + + + + + /// Container for all fluid data needed by solvers. struct BlackoilFluidData : public BlackoilDefs { From 6df82bca1ca757e955e7926a3e9ad35cf44b4ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 28 Jun 2011 10:27:41 +0200 Subject: [PATCH 093/113] Made the new compute...() methods const. --- dune/porsol/blackoil/BlackoilFluid.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 1acb42ea..081fd84d 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -131,7 +131,7 @@ namespace Opm /// Input: p, z /// Output: B, R template - void computeBAndR(States& states) + void computeBAndR(States& states) const { const std::vector& p = states.phase_pressure; const std::vector& z = states.surface_volume_density; @@ -144,7 +144,7 @@ namespace Opm /// Input: p, z /// Output: B, R, mu template - void computePvtNoDerivs(States& states) + void computePvtNoDerivs(States& states) const { computeBAndR(states); const std::vector& p = states.phase_pressure; @@ -156,7 +156,7 @@ namespace Opm /// Input: p, z /// Output: B, dB/dp, R, dR/dp, mu template - void computePvt(States& states) + void computePvt(States& states) const { const std::vector& p = states.phase_pressure; const std::vector& z = states.surface_volume_density; @@ -173,7 +173,7 @@ namespace Opm /// Input: B, R /// Output: A template - void computeStateMatrix(States& states) + void computeStateMatrix(States& states) const { int num = states.state_matrix.size(); states.state_matrix.resize(num); @@ -198,7 +198,7 @@ namespace Opm /// Input: z, B, dB/dp, R, dR/dp /// Output: A, u, sum(u), s, c, cT, ex template - void computePvtDepending(States& states) + void computePvtDepending(States& states) const { int num = states.state_matrix.size(); states.state_matrix.resize(num); @@ -231,7 +231,7 @@ namespace Opm /// Input: s, mu /// Output: kr, lambda template - void computeMobilitiesNoDerivs(States& states) + void computeMobilitiesNoDerivs(States& states) const { int num = states.state_matrix.size(); states.relperm.resize(num); @@ -253,7 +253,7 @@ namespace Opm /// Input: s, mu /// Output: kr, dkr/ds, lambda, dlambda/ds template - void computeMobilities(States& states) + void computeMobilities(States& states) const { int num = states.state_matrix.size(); states.relperm.resize(num); From c68372e76b86f43fb537e2b387012f4d2102128f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 28 Jun 2011 11:17:50 +0200 Subject: [PATCH 094/113] Fixed sizing bugs and more. --- dune/porsol/blackoil/BlackoilFluid.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 081fd84d..0580f2f0 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -175,7 +175,7 @@ namespace Opm template void computeStateMatrix(States& states) const { - int num = states.state_matrix.size(); + int num = states.formation_volume_factor.size(); states.state_matrix.resize(num); #pragma omp parallel for for (int i = 0; i < num; ++i) { @@ -200,7 +200,7 @@ namespace Opm template void computePvtDepending(States& states) const { - int num = states.state_matrix.size(); + int num = states.formation_volume_factor.size(); states.state_matrix.resize(num); states.phase_volume_density.resize(num); states.total_phase_volume_density.resize(num); @@ -233,7 +233,7 @@ namespace Opm template void computeMobilitiesNoDerivs(States& states) const { - int num = states.state_matrix.size(); + int num = states.saturation.size(); states.relperm.resize(num); states.mobility.resize(num); #pragma omp parallel for @@ -255,7 +255,7 @@ namespace Opm template void computeMobilities(States& states) const { - int num = states.state_matrix.size(); + int num = states.saturation.size(); states.relperm.resize(num); states.relperm_deriv.resize(num); states.mobility.resize(num); @@ -560,7 +560,7 @@ namespace Opm // Also compute the potentials. PhaseVec pot[2]; for (int phase = 0; phase < np; ++phase) { - gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + gravcapf[face][phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; pot[0][phase] = phase_p[0][phase] + gravcapf[face][phase]; pot[1][phase] = phase_p[1][phase]; } @@ -600,23 +600,23 @@ namespace Opm if (pot[0][phase] == pot[1][phase]) { // Average. double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); - phasemobf[np*face + phase] = aver; + phasemobf[face][phase] = aver; for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] + phasemobf_deriv[face][phase][p2] = phasemob_deriv[0][phase][p2] + phasemob_deriv[1][phase][p2]; } } else { // Upwind. int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; - phasemobf[np*face + phase] = phase_mob[upwind][phase]; + phasemobf[face][phase] = phase_mob[upwind][phase]; for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; + phasemobf_deriv[face][phase][p2] = phasemob_deriv[upwind][phase][p2]; } } } // Find faceA. FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); - std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); + std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face][0][0]); } // Find faceA. Slower, since it does too much. From 1cfc197551459645988ac38a20494eb27d4f9f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 28 Jun 2011 18:08:37 +0200 Subject: [PATCH 095/113] Removed unused code. --- dune/porsol/blackoil/BlackoilFluid.hpp | 457 ------------------ .../blackoil/fluid/FluidStateBlackoil.hpp | 23 - 2 files changed, 480 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 0580f2f0..494b6f6c 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -76,37 +76,6 @@ namespace Opm return state; } - void computeManyStates(const std::vector& phase_pressure, - const std::vector& z, - ManyFluidStatesBlackoil& state) const - { - int num = phase_pressure.size(); - state.temperature_.clear(); - state.temperature_.resize(num, 300.0); - state.phase_pressure_ = phase_pressure; - state.surface_volume_ = z; - // FluidSystemBlackoil<>::computeManyEquilibria(state); // Sets everything but relperm and mobility. - computeManyEquilibria(state); - state.relperm_.resize(num); - state.drelperm_.resize(num); - state.mobility_.resize(num); - state.dmobility_.resize(num); -#pragma omp parallel for - for (int i = 0; i < num; ++i) { - FluidMatrixInteractionBlackoil::kr(state.relperm_[i], fmi_params_, - state.saturation_[i], state.temperature_[i]); - FluidMatrixInteractionBlackoil::dkr(state.drelperm_[i], fmi_params_, - state.saturation_[i], state.temperature_[i]); - for (int phase = 0; phase < numPhases; ++phase) { - state.mobility_[i][phase] = state.relperm_[i][phase]/state.viscosity_[i][phase]; - for (int p2 = 0; p2 < numPhases; ++p2) { - // Ignoring pressure variation in viscosity for this one. - state.dmobility_[i][phase][p2] = state.drelperm_[i][phase][p2]/state.viscosity_[i][phase]; - } - } - } - } - const CompVec& surfaceDensities() const { @@ -336,58 +305,7 @@ namespace Opm mu[Liquid] = pvt_.getViscosity(p[Liquid], z, Liquid); } - /*! - * \brief Assuming the surface volumes and the pressures of all - * phases are known, compute everything except relperm and - * mobility. - */ - template - void computeManyEquilibria(ManyFluidStates& fluid_state) const - { - // Get B and R factors, viscosities. Vectorized at lower level. - const std::vector& pv = fluid_state.phase_pressure_; - const std::vector& zv = fluid_state.surface_volume_; - std::vector& Bv = fluid_state.formation_volume_factor_; - std::vector dBv; - pvt_.dBdp(pv, zv, Bv, dBv); - std::vector& Rv = fluid_state.solution_factor_; - std::vector dRv; - pvt_.dRdp(pv, zv, Rv, dRv); - std::vector& muv = fluid_state.viscosity_; - pvt_.getViscosity(pv, zv, muv); - // The rest is vectorized in this function. - int num = pv.size(); - fluid_state.phase_to_comp_.resize(num); - fluid_state.phase_volume_density_.resize(num); - fluid_state.total_phase_volume_density_.resize(num); - fluid_state.phase_to_comp_.resize(num); - fluid_state.saturation_.resize(num); - fluid_state.phase_compressibility_.resize(num); - fluid_state.total_compressibility_.resize(num); - fluid_state.experimental_term_.resize(num); -#pragma omp parallel for - for (int i = 0; i < num; ++i) { - // Convenience vars. - const PhaseVec& B = Bv[i]; - const PhaseVec& dB = dBv[i]; - const PhaseVec& R = Rv[i]; - const PhaseVec& dR = dRv[i]; - const CompVec& z = zv[i]; - - PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; - PhaseVec& u = fluid_state.phase_volume_density_[i]; - double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_[i]; - PhaseVec& s = fluid_state.saturation_[i]; - PhaseVec& cp = fluid_state.phase_compressibility_[i]; - double& tot_comp = fluid_state.total_compressibility_[i]; - double& exp_term = fluid_state.experimental_term_[i]; - - computeSingleEquilibrium(B, dB, R, dR, z, - At, u, tot_phase_vol_dens, - s, cp, tot_comp, exp_term); - } - } static void computeSingleEquilibrium(const PhaseVec& B, const PhaseVec& dB, @@ -630,381 +548,6 @@ namespace Opm }; - - - - - - - /// Container for all fluid data needed by solvers. - struct BlackoilFluidData : public BlackoilDefs - { - // Per-cell data. - std::vector totcompr; // Total compressibility. - std::vector totphasevol_density; // Total volume filled by fluid phases - // per pore volume. - std::vector voldiscr; // Volume discrepancy = (totphasevol_dens - 1)*pv/dt - std::vector relvoldiscr; // Relative volume discrepancy = |totphasevol_dens - 1| - std::vector cellA; // A = RB^{-1}. Fortran ordering, flat storage. - std::vector saturation; // Saturation. - std::vector frac_flow; // Fractional flow. - std::vector rel_perm; // Relative permeability. - std::vector viscosity; // Viscosity. - - // Extra data. - std::vector expjacterm; - - // Per-face data. - std::vector faceA; // A = RB^{-1}. Fortran ordering, flat storage. - std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). - std::vector phasemobc; // Phase mobilities per cell. - std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). - std::vector phasemobc_deriv; // Phase mobilities derivatives per cell. - std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. - - public: - template - void compute(const Grid& grid, - const Rock& rock, - const BlackoilFluid& fluid, - const typename Grid::Vector gravity, - const std::vector& cell_pressure, - const std::vector& face_pressure, - const std::vector& cell_z, - const CompVec& bdy_z, - const double dt) - { - int num_cells = cell_z.size(); - ASSERT(num_cells == grid.numCells()); - int num_faces = face_pressure.size(); - ASSERT(num_faces == grid.numFaces()); - const int np = numPhases; - const int nc = numComponents; - bool nonzero_gravity = gravity.two_norm() > 0.0; - BOOST_STATIC_ASSERT(np == nc); - totcompr.resize(num_cells); - totphasevol_density.resize(num_cells); - voldiscr.resize(num_cells); - relvoldiscr.resize(num_cells); - saturation.resize(num_cells); - frac_flow.resize(num_cells); - rel_perm.resize(num_cells); - viscosity.resize(num_cells); - expjacterm.resize(num_cells); - cellA.resize(num_cells*nc*np); - faceA.resize(num_faces*nc*np); - phasemobf.resize(np*num_faces); - phasemobc.resize(num_cells); - phasemobf_deriv.resize(np*np*num_faces); - phasemobc_deriv.resize(np*np*num_cells); - gravcapf.resize(np*num_faces); - BOOST_STATIC_ASSERT(np == 3); -#pragma omp parallel for - for (int cell = 0; cell < num_cells; ++cell) { - FluidStateBlackoil state = fluid.computeState(cell_pressure[cell], cell_z[cell]); - totcompr[cell] = state.total_compressibility_; - totphasevol_density[cell] = state.total_phase_volume_density_; - double pv = rock.porosity(cell)*grid.cellVolume(cell); - voldiscr[cell] = (totphasevol_density[cell] - 1.0)*pv/dt; - relvoldiscr[cell] = std::fabs(totphasevol_density[cell] - 1.0); - saturation[cell] = state.saturation_; - rel_perm[cell] = state.relperm_; - viscosity[cell] = state.viscosity_; - phasemobc[cell] = state.mobility_; - phasemobc_deriv[cell] = state.dmobility_; - std::copy(&state.phase_to_comp_[0][0], &state.phase_to_comp_[0][0] + nc*np, &cellA[cell*nc*np]); - // Fractional flow must be calculated. - double total_mobility = 0.0; - for (int phase = 0; phase < numPhases; ++phase) { - total_mobility += state.mobility_[phase]; - } - frac_flow[cell] = state.mobility_; - frac_flow[cell] /= total_mobility; - - // Experimental - expjacterm[cell] = state.experimental_term_; - } - - // Obtain properties from both sides of the face. -#pragma omp parallel for - for (int face = 0; face < num_faces; ++face) { - typedef typename Grid::Vector Vec; - Vec fc = grid.faceCentroid(face); - int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; - - // Get pressures and compute gravity contributions, - // to decide upwind directions. - PhaseVec phase_p[2]; - PhaseVec gravcontrib[2]; - for (int j = 0; j < 2; ++j) { - if (c[j] >= 0) { - // Pressures - phase_p[j] = cell_pressure[c[j]]; - // Gravity contribution. - if (nonzero_gravity) { - Vec cdiff = fc; - cdiff -= grid.cellCentroid(c[j]); - gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; - gravcontrib[j] *= (cdiff*gravity); - } else { - gravcontrib[j] = 0.0; - } - } else { - // Pressures - phase_p[j] = face_pressure[face]; - // Gravity contribution. - gravcontrib[j] = 0.0; - } - } - - // Gravity contribution: - // gravcapf = rho_1*g*(z_12 - z_1) - rho_2*g*(z_12 - z_2) - // where _1 and _2 refers to two neigbour cells, z is the - // z coordinate of the centroid, and z_12 is the face centroid. - // Also compute the potentials. - PhaseVec pot[2]; - for (int phase = 0; phase < np; ++phase) { - gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; - pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; - pot[1][phase] = phase_p[1][phase]; - } - - // Now we can easily find the upwind direction for every phase, - // we can also tell which boundary faces are inflow bdys. - - // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. - // Get mobilities and derivatives. - CompVec face_z(0.0); - double face_z_factor = 0.5; - PhaseVec phase_mob[2]; - PhaseJacobian phasemob_deriv[2]; - for (int j = 0; j < 2; ++j) { - if (c[j] >= 0) { - face_z += cell_z[c[j]]; - phase_mob[j] = phasemobc[c[j]]; - phasemob_deriv[j] = phasemobc_deriv[c[j]]; - } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { - // Inflow boundary. - face_z += bdy_z; - FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); - phase_mob[j] = bdy_state.mobility_; - phasemob_deriv[j] = bdy_state.dmobility_; - } else { - // For outflow or noflow boundaries, only cell z is used. - face_z_factor = 1.0; - // Also, make sure the boundary data are not used for mobilities. - pot[j] = -1e100; - } - } - face_z *= face_z_factor; - - // Computing upwind mobilities and derivatives - for (int phase = 0; phase < np; ++phase) { - if (pot[0][phase] == pot[1][phase]) { - // Average. - double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); - phasemobf[np*face + phase] = aver; - for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] - + phasemob_deriv[1][phase][p2]; - } - } else { - // Upwind. - int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; - phasemobf[np*face + phase] = phase_mob[upwind][phase]; - for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; - } - } - } - - // Find faceA. - FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); - std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); - } - } - - - - - public: - template - void computeNew(const Grid& grid, - const Rock& rock, - const BlackoilFluid& fluid, - const typename Grid::Vector gravity, - const std::vector& cell_pressure, - const std::vector& face_pressure, - const std::vector& cell_z, - const CompVec& bdy_z, - const double dt) - { - int num_cells = cell_z.size(); - ASSERT(num_cells == grid.numCells()); - int num_faces = face_pressure.size(); - ASSERT(num_faces == grid.numFaces()); - const int np = numPhases; - const int nc = numComponents; - bool nonzero_gravity = gravity.two_norm() > 0.0; - BOOST_STATIC_ASSERT(np == nc); - totcompr.resize(num_cells); - totphasevol_density.resize(num_cells); - voldiscr.resize(num_cells); - relvoldiscr.resize(num_cells); - saturation.resize(num_cells); - frac_flow.resize(num_cells); - rel_perm.resize(num_cells); - viscosity.resize(num_cells); - expjacterm.resize(num_cells); - cellA.resize(num_cells*nc*np); - faceA.resize(num_faces*nc*np); - phasemobf.resize(np*num_faces); - phasemobc.resize(num_cells); - phasemobf_deriv.resize(np*np*num_faces); - phasemobc_deriv.resize(np*np*num_cells); - gravcapf.resize(np*num_faces); - BOOST_STATIC_ASSERT(np == 3); - - // Compute and copy properties. - ManyFluidStatesBlackoil state; - fluid.computeManyStates(cell_pressure, cell_z, state); - totcompr = state.total_compressibility_; - totphasevol_density = state.total_phase_volume_density_; - saturation = state.saturation_; - rel_perm = state.relperm_; - viscosity = state.viscosity_; - phasemobc = state.mobility_; - phasemobc_deriv = state.dmobility_; - std::copy(&state.phase_to_comp_[0][0][0], - &state.phase_to_comp_[0][0][0] + num_cells*nc*np, - &cellA[0]); - expjacterm = state.experimental_term_; - -#pragma omp parallel for - for (int cell = 0; cell < num_cells; ++cell) { - double pv = rock.porosity(cell)*grid.cellVolume(cell); - voldiscr[cell] = (totphasevol_density[cell] - 1.0)*pv/dt; - relvoldiscr[cell] = std::fabs(totphasevol_density[cell] - 1.0); - - // Fractional flow must be calculated. - double total_mobility = 0.0; - for (int phase = 0; phase < numPhases; ++phase) { - total_mobility += state.mobility_[cell][phase]; - } - frac_flow[cell] = state.mobility_[cell]; - frac_flow[cell] /= total_mobility; - } - - // std::vector face_z_vec(num_faces); -#pragma omp parallel for - for (int face = 0; face < num_faces; ++face) { - // Obtain properties from both sides of the face. - typedef typename Grid::Vector Vec; - Vec fc = grid.faceCentroid(face); - int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) }; - - // Get pressures and compute gravity contributions, - // to decide upwind directions. - PhaseVec phase_p[2]; - PhaseVec gravcontrib[2]; - for (int j = 0; j < 2; ++j) { - if (c[j] >= 0) { - // Pressures - phase_p[j] = cell_pressure[c[j]]; - // Gravity contribution. - if (nonzero_gravity) { - Vec cdiff = fc; - cdiff -= grid.cellCentroid(c[j]); - gravcontrib[j] = fluid.phaseDensities(&cellA[np*nc*c[j]]);; - gravcontrib[j] *= (cdiff*gravity); - } else { - gravcontrib[j] = 0.0; - } - } else { - // Pressures - phase_p[j] = face_pressure[face]; - // Gravity contribution. - gravcontrib[j] = 0.0; - } - } - - // Gravity contribution: - // gravcapf = rho_1*g*(z_12 - z_1) - rho_2*g*(z_12 - z_2) - // where _1 and _2 refers to two neigbour cells, z is the - // z coordinate of the centroid, and z_12 is the face centroid. - // Also compute the potentials. - PhaseVec pot[2]; - for (int phase = 0; phase < np; ++phase) { - gravcapf[np*face + phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; - pot[0][phase] = phase_p[0][phase] + gravcapf[np*face + phase]; - pot[1][phase] = phase_p[1][phase]; - } - - // Now we can easily find the upwind direction for every phase, - // we can also tell which boundary faces are inflow bdys. - - // Compute face_z, which is averaged from the cells, unless on outflow or noflow bdy. - // Get mobilities and derivatives. - CompVec face_z(0.0); - double face_z_factor = 0.5; - PhaseVec phase_mob[2]; - PhaseJacobian phasemob_deriv[2]; - for (int j = 0; j < 2; ++j) { - if (c[j] >= 0) { - face_z += cell_z[c[j]]; - phase_mob[j] = phasemobc[c[j]]; - phasemob_deriv[j] = phasemobc_deriv[c[j]]; - } else if (pot[j][Liquid] > pot[(j+1)%2][Liquid]) { - // Inflow boundary. - face_z += bdy_z; - FluidStateBlackoil bdy_state = fluid.computeState(face_pressure[face], bdy_z); - phase_mob[j] = bdy_state.mobility_; - phasemob_deriv[j] = bdy_state.dmobility_; - } else { - // For outflow or noflow boundaries, only cell z is used. - face_z_factor = 1.0; - // Also, make sure the boundary data are not used for mobilities. - pot[j] = -1e100; - } - } - face_z *= face_z_factor; - // face_z_vec[face] = face_z; - - // Computing upwind mobilities and derivatives - for (int phase = 0; phase < np; ++phase) { - if (pot[0][phase] == pot[1][phase]) { - // Average. - double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); - phasemobf[np*face + phase] = aver; - for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[0][phase][p2] - + phasemob_deriv[1][phase][p2]; - } - } else { - // Upwind. - int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; - phasemobf[np*face + phase] = phase_mob[upwind][phase]; - for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[np*np*face + np*phase + p2] = phasemob_deriv[upwind][phase][p2]; - } - } - } - // Find faceA. - FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); - std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face*nc*np]); - } - - // Find faceA. Slower, since it does too much. -// ManyFluidStatesBlackoil face_state; -// fluid.computeManyStates(face_pressure, face_z_vec, face_state); -// const double* fA = &face_state.phase_to_comp_[0][0][0]; -// std::copy(fA, fA + num_faces*nc*np, &faceA[0]); - } - - - }; - - } // namespace Opm #endif // OPM_BLACKOILFLUID_HEADER_INCLUDED diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp index 1dcbcb99..dfc8a17b 100644 --- a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp +++ b/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp @@ -50,29 +50,6 @@ namespace Opm PhaseJacobian dmobility_; }; - /*! - * \brief Multiple fluid states for a black oil model. - */ - struct ManyFluidStatesBlackoil : public BlackoilDefs - { - std::vector temperature_; - std::vector surface_volume_; - std::vector phase_pressure_; - std::vector phase_volume_density_; - std::vector total_phase_volume_density_; - std::vector formation_volume_factor_; - std::vector solution_factor_; - std::vector phase_to_comp_; // RB^{-1} in Fortran ordering - std::vector saturation_; - std::vector phase_compressibility_; - std::vector total_compressibility_; - std::vector experimental_term_; - std::vector viscosity_; - std::vector relperm_; - std::vector drelperm_; - std::vector mobility_; - std::vector dmobility_; - }; /*! * \brief Multiple fluid states for a black oil model. From d326b5ca5faf55f5745c528c54da87ac9ef97472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 29 Jun 2011 14:20:50 +0200 Subject: [PATCH 096/113] Added FaceFluidData. Further restructuring of fluid computations. --- dune/porsol/blackoil/BlackoilFluid.hpp | 94 +++++++++++++++++--------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 494b6f6c..0e4e22a7 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -379,6 +379,28 @@ namespace Opm + struct FaceFluidData : public BlackoilDefs + { + // Canonical state variables. + std::vector surface_volume_density; // z + std::vector phase_pressure; // p + + // Variables from PVT functions. + std::vector formation_volume_factor; // B + std::vector solution_factor; // R + + // Variables computed from PVT data. + // The A matrices are all in Fortran order (or, equivalently, + // we store the transposes). + std::vector state_matrix; // A' = (RB^{-1})' + + // Variables computed from saturation. + std::vector mobility; // lambda + std::vector mobility_deriv; // dlambda/ds + + // Gravity and/or capillary pressure potential differences. + std::vector gravity_potential; // (\rho g \delta z)-ish contribution per face + }; struct AllFluidData : public BlackoilDefs @@ -389,10 +411,7 @@ namespace Opm std::vector relvoldiscr; // Per-face data. - std::vector faceA; // A = RB^{-1}. Fortran ordering. - std::vector phasemobf; // Phase mobilities. Flat storage (numPhases per face). - std::vector phasemobf_deriv; // Phase mobility derivatives. Flat storage (numPhases^2 per face). - std::vector gravcapf; // Gravity (\rho g \delta z-ish) contribution per face, flat storage. + FaceFluidData face_data; public: template @@ -408,11 +427,8 @@ namespace Opm { int num_cells = cell_z.size(); ASSERT(num_cells == grid.numCells()); - int num_faces = face_pressure.size(); - ASSERT(num_faces == grid.numFaces()); const int np = numPhases; const int nc = numComponents; - bool nonzero_gravity = gravity.two_norm() > 0.0; BOOST_STATIC_ASSERT(np == nc); BOOST_STATIC_ASSERT(np == 3); @@ -433,12 +449,37 @@ namespace Opm relvoldiscr[cell] = std::fabs(cell_data.total_phase_volume_density[cell] - 1.0); } - // Compute face properties. - faceA.resize(num_faces); - phasemobf.resize(num_faces); - phasemobf_deriv.resize(num_faces); - gravcapf.resize(num_faces); - // std::vector face_z_vec(num_faces); + + // Compute upwinded face properties, including z. + computeUpwindProperties(grid, fluid, gravity, + cell_pressure, face_pressure, + cell_z, bdy_z); + + // Compute state matrices for faces. + // p, z -> B, R, A + face_data.phase_pressure = face_pressure; + fluid.computeBAndR(face_data); + fluid.computeStateMatrix(face_data); + } + + + template + void computeUpwindProperties(const Grid& grid, + const BlackoilFluid& fluid, + const typename Grid::Vector gravity, + const std::vector& cell_pressure, + const std::vector& face_pressure, + const std::vector& cell_z, + const CompVec& bdy_z) + { + int num_faces = face_pressure.size(); + ASSERT(num_faces == grid.numFaces()); + bool nonzero_gravity = gravity.two_norm() > 0.0; + face_data.state_matrix.resize(num_faces); + face_data.mobility.resize(num_faces); + face_data.mobility_deriv.resize(num_faces); + face_data.gravity_potential.resize(num_faces); + face_data.surface_volume_density.resize(num_faces); #pragma omp parallel for for (int face = 0; face < num_faces; ++face) { // Obtain properties from both sides of the face. @@ -477,9 +518,9 @@ namespace Opm // z coordinate of the centroid, and z_12 is the face centroid. // Also compute the potentials. PhaseVec pot[2]; - for (int phase = 0; phase < np; ++phase) { - gravcapf[face][phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; - pot[0][phase] = phase_p[0][phase] + gravcapf[face][phase]; + for (int phase = 0; phase < numPhases; ++phase) { + face_data.gravity_potential[face][phase] = gravcontrib[0][phase] - gravcontrib[1][phase]; + pot[0][phase] = phase_p[0][phase] + face_data.gravity_potential[face][phase]; pot[1][phase] = phase_p[1][phase]; } @@ -511,37 +552,28 @@ namespace Opm } } face_z *= face_z_factor; - // face_z_vec[face] = face_z; + face_data.surface_volume_density[face] = face_z; // Computing upwind mobilities and derivatives - for (int phase = 0; phase < np; ++phase) { + for (int phase = 0; phase < numPhases; ++phase) { if (pot[0][phase] == pot[1][phase]) { // Average. double aver = 0.5*(phase_mob[0][phase] + phase_mob[1][phase]); - phasemobf[face][phase] = aver; + face_data.mobility[face][phase] = aver; for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[face][phase][p2] = phasemob_deriv[0][phase][p2] + face_data.mobility_deriv[face][phase][p2] = phasemob_deriv[0][phase][p2] + phasemob_deriv[1][phase][p2]; } } else { // Upwind. int upwind = pot[0][phase] > pot[1][phase] ? 0 : 1; - phasemobf[face][phase] = phase_mob[upwind][phase]; + face_data.mobility[face][phase] = phase_mob[upwind][phase]; for (int p2 = 0; p2 < numPhases; ++p2) { - phasemobf_deriv[face][phase][p2] = phasemob_deriv[upwind][phase][p2]; + face_data.mobility_deriv[face][phase][p2] = phasemob_deriv[upwind][phase][p2]; } } } - // Find faceA. - FluidStateBlackoil face_state = fluid.computeState(face_pressure[face], face_z); - std::copy(&face_state.phase_to_comp_[0][0], &face_state.phase_to_comp_[0][0] + nc*np, &faceA[face][0][0]); } - - // Find faceA. Slower, since it does too much. -// ManyFluidStatesBlackoil face_state; -// fluid.computeManyStates(face_pressure, face_z_vec, face_state); -// const double* fA = &face_state.phase_to_comp_[0][0][0]; -// std::copy(fA, fA + num_faces*nc*np, &faceA[0]); } From 79778eb7f682f7c40498b863fee0b8ad29c5c92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 29 Jun 2011 14:50:57 +0200 Subject: [PATCH 097/113] Removed unused class FluidSystemBlackoil. --- dune/porsol/blackoil/BlackoilFluid.hpp | 2 +- .../blackoil/fluid/FluidSystemBlackoil.hpp | 525 ------------------ 2 files changed, 1 insertion(+), 526 deletions(-) delete mode 100644 dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/dune/porsol/blackoil/BlackoilFluid.hpp index 0e4e22a7..d1cd6df2 100644 --- a/dune/porsol/blackoil/BlackoilFluid.hpp +++ b/dune/porsol/blackoil/BlackoilFluid.hpp @@ -22,8 +22,8 @@ #include -#include #include +#include #include #include #include diff --git a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp b/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp deleted file mode 100644 index 89d95395..00000000 --- a/dune/porsol/blackoil/fluid/FluidSystemBlackoil.hpp +++ /dev/null @@ -1,525 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2009 by Andreas Lauser - * Institute of Hydraulic Engineering * - * University of Stuttgart, Germany * - * email: .@iws.uni-stuttgart.de * - * * - * This program 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 2 of the License, or * - * (at your option) any later version, as long as this copyright notice * - * is included in its original form. * - * * - * This program is distributed WITHOUT ANY WARRANTY. * - *****************************************************************************/ -/* - Copyright 2010 SINTEF ICT, Applied Mathematics. - - 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_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED -#define OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED - -#include "BlackoilPVT.hpp" -#include "BlackoilDefs.hpp" -#include -#include -#include - -namespace Opm -{ - -// Forward declaration needed by associated parameters classes. -template -class FluidSystemBlackoil; - -// Parameters for the black oil fluid system. -class FluidSystemBlackoilParameters -{ -public: - void init(const Dune::EclipseGridParser& ep) - { - pvt_.init(ep); - } -private: - template - friend class FluidSystemBlackoil; - BlackoilPVT pvt_; -}; - - -/*! - * \brief A black oil fluid system. - */ -template -class FluidSystemBlackoil : public BlackoilDefs -{ -public: - typedef ParamsT Params; - - /*! - * \brief Initialize system from input. - */ - static void init(const Dune::EclipseGridParser& ep) - { - params().init(ep); - } - - /*! - * \brief Return a human-readable phase name. - */ - static const char* phaseName(int phaseIdx) - { - switch (phaseIdx) { - case Aqua: return "aqua"; - case Vapour: return "vapour"; - case Liquid: return "liquid"; - default: throw std::logic_error("No such phase."); - } - } - - /*! - * \brief Return a human-readable component name. - */ - static const char* componentName(int compIdx) - { - switch (compIdx) { - case Water: return "water"; - case Gas: return "gas"; - case Oil: return "oil"; - default: throw std::logic_error("No such component."); - } - } - - - /*! - * \brief Return the molar mass of a component [kg/mol]. - */ - static Scalar molarMass(int compIdx) - { - throw std::logic_error("molarMass() not implemented."); - } - - - /*! - * \brief Given a phase's composition, temperature, pressure, and - * the partial pressures of all components, return its - * density [kg/m^3]. - */ - template - static Scalar phaseDensity(int phaseIdx, - Scalar temperature, - Scalar pressure, - const FluidState &fluidState) - { - throw std::logic_error("phaseDensity() not implemented."); - } - - /*! - * \brief Given a phase's composition, temperature and pressure, - * return its viscosity. - */ - template - static Scalar phaseViscosity(int phaseIdx, - Scalar temperature, - Scalar pressure, - const FluidState &fluidState) - { - throw std::logic_error("phaseViscosity() not implemented."); - } - - - /*! - * \brief Assuming the surface volumes and the pressures of all - * phases are known, compute everything except relperm and - * mobility. - */ - template - static void computeEquilibrium(FluidState& fluid_state) - { - // Get B and R factors. - const PhaseVec& p = fluid_state.phase_pressure_; - const CompVec& z = fluid_state.surface_volume_; - PhaseVec& B = fluid_state.formation_volume_factor_; - B[Aqua] = params().pvt_.B(p[Aqua], z, Aqua); - B[Vapour] = params().pvt_.B(p[Vapour], z, Vapour); - B[Liquid] = params().pvt_.B(p[Liquid], z, Liquid); - PhaseVec& R = fluid_state.solution_factor_; - R[Aqua] = 0.0; - R[Vapour] = params().pvt_.R(p[Vapour], z, Vapour); - R[Liquid] = params().pvt_.R(p[Liquid], z, Liquid); - PhaseVec dB; - dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); - dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); - dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); - PhaseVec dR; - dR[Aqua] = 0.0; - dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); - dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); - - // Convenience vars. - PhaseToCompMatrix& At = fluid_state.phase_to_comp_; - PhaseVec& u = fluid_state.phase_volume_density_; - double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_; - PhaseVec& s = fluid_state.saturation_; - PhaseVec& cp = fluid_state.phase_compressibility_; - double& tot_comp = fluid_state.total_compressibility_; - double& exp_term = fluid_state.experimental_term_; - - computeSingleEquilibrium(B, dB, R, dR, z, - At, u, tot_phase_vol_dens, - s, cp, tot_comp, exp_term); - - // Compute viscosities. - PhaseVec& mu = fluid_state.viscosity_; - mu[Aqua] = params().pvt_.getViscosity(p[Aqua], z, Aqua); - mu[Vapour] = params().pvt_.getViscosity(p[Vapour], z, Vapour); - mu[Liquid] = params().pvt_.getViscosity(p[Liquid], z, Liquid); - - /* - // Set the A matrix (A = RB^{-1}) - Dune::SharedFortranMatrix A(numComponents, numPhases, &fluid_state.phase_to_comp_[0][0]); - zero(A); - A(Water, Aqua) = 1.0/B[Aqua]; - A(Gas, Vapour) = 1.0/B[Vapour]; - A(Gas, Liquid) = R[Liquid]/B[Liquid]; - A(Oil, Vapour) = R[Vapour]/B[Vapour]; - A(Oil, Liquid) = 1.0/B[Liquid]; - - // Update phase volumes. This is the same as multiplying with A^{-1} - PhaseVec& u = fluid_state.phase_volume_density_; - double detR = 1.0 - R[Vapour]*R[Liquid]; - u[Aqua] = B[Aqua]*z[Water]; - u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; - u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; - fluid_state.total_phase_volume_density_ = u[Aqua] + u[Vapour] + u[Liquid]; - - // Update saturations. - double sumu = fluid_state.total_phase_volume_density_; - PhaseVec& s = fluid_state.saturation_; - for (int phase = 0; phase < numPhases; ++phase) { - s[phase] = u[phase]/sumu; - } - - // Compute viscosities. - PhaseVec& mu = fluid_state.viscosity_; - mu[Aqua] = params().pvt_.getViscosity(p[Aqua], z, Aqua); - mu[Vapour] = params().pvt_.getViscosity(p[Vapour], z, Vapour); - mu[Liquid] = params().pvt_.getViscosity(p[Liquid], z, Liquid); - - // Phase compressibilities. - PhaseVec& cp = fluid_state.phase_compressibility_; -// double dB[3]; -// dB[Aqua] = params().pvt_.dBdp(p[Aqua], z, Aqua); -// dB[Vapour] = params().pvt_.dBdp(p[Vapour], z, Vapour); -// dB[Liquid] = params().pvt_.dBdp(p[Liquid], z, Liquid); -// double dR[3]; // Only using 2 of them, though. -// dR[Vapour] = params().pvt_.dRdp(p[Vapour], z, Vapour); -// dR[Liquid] = params().pvt_.dRdp(p[Liquid], z, Liquid); - // Set the derivative of the A matrix (A = RB^{-1}) - double data_for_dA[numComponents*numPhases]; - Dune::SharedFortranMatrix dA(numComponents, numPhases, data_for_dA); - zero(dA); - dA(Water, Aqua) = -dB[Aqua]/(B[Aqua]*B[Aqua]); - dA(Gas, Vapour) = -dB[Vapour]/(B[Vapour]*B[Vapour]); - dA(Oil, Liquid) = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. - dA(Gas, Liquid) = dA(Oil, Liquid)*R[Liquid] + dR[Liquid]/B[Liquid]; - dA(Oil, Vapour) = dA(Gas, Vapour)*R[Vapour] + dR[Vapour]/B[Vapour]; - double data_for_Ai[numComponents*numPhases]; - Dune::SharedFortranMatrix Ai(numComponents, numPhases, data_for_Ai); - // Ai = A; // This does not make a deep copy. - std::copy(A.data(), A.data() + numComponents*numPhases, Ai.data()); - Dune::invert(Ai); - double data_for_C[numComponents*numPhases]; - Dune::SharedFortranMatrix C(numComponents, numPhases, data_for_C); - Dune::prod(Ai, dA, C); - //CompVec ones(1.0); - //cp = Dune::prod(C, ones); // Probably C' and not C; we want phasewise compressibilities: - cp[Aqua] = C(Water, Aqua); - cp[Liquid] = C(Oil, Liquid) + C(Gas, Liquid); - cp[Vapour] = C(Gas, Vapour) + C(Oil, Vapour); - fluid_state.total_compressibility_ = cp*s; - - // Experimental term. - PhaseVec tmp = prod(Ai, prod(dA, prod(Ai, z))); - fluid_state.experimental_term_ = tmp[Aqua] + tmp[Liquid] + tmp[Gas]; - */ - } - - - static void computeSingleEquilibrium(const PhaseVec& B, - const PhaseVec& dB, - const PhaseVec& R, - const PhaseVec& dR, - const CompVec& z, - PhaseToCompMatrix& At, - PhaseVec& u, - double& tot_phase_vol_dens, - PhaseVec& s, - PhaseVec& cp, - double& tot_comp, - double& exp_term) - { - // Set the A matrix (A = RB^{-1}) - // Using At since we really want Fortran ordering - // (since ultimately that is what the opmpressure - // C library expects). - // PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; - At = 0.0; - At[Aqua][Water] = 1.0/B[Aqua]; - At[Vapour][Gas] = 1.0/B[Vapour]; - At[Liquid][Gas] = R[Liquid]/B[Liquid]; - At[Vapour][Oil] = R[Vapour]/B[Vapour]; - At[Liquid][Oil] = 1.0/B[Liquid]; - - // Update phase volumes. This is the same as multiplying with A^{-1} - // PhaseVec& u = fluid_state.phase_volume_density_[i]; - double detR = 1.0 - R[Vapour]*R[Liquid]; - u[Aqua] = B[Aqua]*z[Water]; - u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; - u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; - tot_phase_vol_dens = u[Aqua] + u[Vapour] + u[Liquid]; - - // PhaseVec& s = fluid_state.saturation_[i]; - for (int phase = 0; phase < numPhases; ++phase) { - s[phase] = u[phase]/tot_phase_vol_dens; - } - - // Phase compressibilities. - // PhaseVec& cp = fluid_state.phase_compressibility_[i]; - // Set the derivative of the A matrix (A = RB^{-1}) - PhaseToCompMatrix dAt(0.0); - dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); - dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); - dAt[Liquid][Oil] = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. - dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; - dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; - - PhaseToCompMatrix Ait; - Dune::FMatrixHelp::invertMatrix(At, Ait); - - PhaseToCompMatrix Ct; - Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); - - cp[Aqua] = Ct[Aqua][Water]; - cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; - cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; - tot_comp = cp*s; - - // Experimental term. - PhaseVec tmp1, tmp2, tmp3; - Ait.mtv(z, tmp1); - dAt.mtv(tmp1, tmp2); - Ait.mtv(tmp2, tmp3); - exp_term = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; - } - - /*! - * \brief Assuming the surface volumes and the pressures of all - * phases are known, compute everything except relperm and - * mobility. - */ - template - static void computeManyEquilibria(ManyFluidStates& fluid_state) - { - // Get B and R factors, viscosities. Vectorized at lower level. - const std::vector& pv = fluid_state.phase_pressure_; - const std::vector& zv = fluid_state.surface_volume_; - std::vector& Bv = fluid_state.formation_volume_factor_; - std::vector dBv; - params().pvt_.dBdp(pv, zv, Bv, dBv); - std::vector& Rv = fluid_state.solution_factor_; - std::vector dRv; - params().pvt_.dRdp(pv, zv, Rv, dRv); - std::vector& muv = fluid_state.viscosity_; - params().pvt_.getViscosity(pv, zv, muv); - - // The rest is vectorized in this function. - int num = pv.size(); - fluid_state.phase_to_comp_.resize(num); - fluid_state.phase_volume_density_.resize(num); - fluid_state.total_phase_volume_density_.resize(num); - fluid_state.phase_to_comp_.resize(num); - fluid_state.saturation_.resize(num); - fluid_state.phase_compressibility_.resize(num); - fluid_state.total_compressibility_.resize(num); - fluid_state.experimental_term_.resize(num); -#pragma omp parallel for - for (int i = 0; i < num; ++i) { - // Convenience vars. - const PhaseVec& B = Bv[i]; - const PhaseVec& dB = dBv[i]; - const PhaseVec& R = Rv[i]; - const PhaseVec& dR = dRv[i]; - const CompVec& z = zv[i]; - - PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; - PhaseVec& u = fluid_state.phase_volume_density_[i]; - double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_[i]; - PhaseVec& s = fluid_state.saturation_[i]; - PhaseVec& cp = fluid_state.phase_compressibility_[i]; - double& tot_comp = fluid_state.total_compressibility_[i]; - double& exp_term = fluid_state.experimental_term_[i]; - - computeSingleEquilibrium(B, dB, R, dR, z, - At, u, tot_phase_vol_dens, - s, cp, tot_comp, exp_term); - /* - // Set the A matrix (A = RB^{-1}) - // Using At since we really want Fortran ordering - // (since ultimately that is what the opmpressure - // C library expects). - PhaseToCompMatrix& At = fluid_state.phase_to_comp_[i]; - At = 0.0; - At[Aqua][Water] = 1.0/B[Aqua]; - At[Vapour][Gas] = 1.0/B[Vapour]; - At[Liquid][Gas] = R[Liquid]/B[Liquid]; - At[Vapour][Oil] = R[Vapour]/B[Vapour]; - At[Liquid][Oil] = 1.0/B[Liquid]; - - // Update phase volumes. This is the same as multiplying with A^{-1} - PhaseVec& u = fluid_state.phase_volume_density_[i]; - double detR = 1.0 - R[Vapour]*R[Liquid]; - u[Aqua] = B[Aqua]*z[Water]; - u[Vapour] = B[Vapour]*(z[Gas] - R[Liquid]*z[Oil])/detR; - u[Liquid] = B[Liquid]*(z[Oil] - R[Vapour]*z[Gas])/detR; - fluid_state.total_phase_volume_density_[i] = u[Aqua] + u[Vapour] + u[Liquid]; - - // Update saturations. - double sumu = fluid_state.total_phase_volume_density_[i]; - PhaseVec& s = fluid_state.saturation_[i]; - for (int phase = 0; phase < numPhases; ++phase) { - s[phase] = u[phase]/sumu; - } - - // Phase compressibilities. - PhaseVec& cp = fluid_state.phase_compressibility_[i]; - // Set the derivative of the A matrix (A = RB^{-1}) - PhaseToCompMatrix dAt(0.0); - dAt[Aqua][Water] = -dB[Aqua]/(B[Aqua]*B[Aqua]); - dAt[Vapour][Gas] = -dB[Vapour]/(B[Vapour]*B[Vapour]); - dAt[Liquid][Oil] = -dB[Liquid]/(B[Liquid]*B[Liquid]); // Different order than above. - dAt[Liquid][Gas] = dAt[Liquid][Oil]*R[Liquid] + dR[Liquid]/B[Liquid]; - dAt[Vapour][Oil] = dAt[Vapour][Gas]*R[Vapour] + dR[Vapour]/B[Vapour]; - - PhaseToCompMatrix Ait; - Dune::FMatrixHelp::invertMatrix(At, Ait); - - PhaseToCompMatrix Ct; - Dune::FMatrixHelp::multMatrix(dAt, Ait, Ct); - - cp[Aqua] = Ct[Aqua][Water]; - cp[Liquid] = Ct[Liquid][Oil] + Ct[Liquid][Gas]; - cp[Vapour] = Ct[Vapour][Gas] + Ct[Vapour][Oil]; - fluid_state.total_compressibility_[i] = cp*s; - - // Experimental term. - PhaseVec tmp1, tmp2, tmp3; - Ait.mtv(z, tmp1); - dAt.mtv(tmp1, tmp2); - Ait.mtv(tmp2, tmp3); - fluid_state.experimental_term_[i] = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; - */ - } - } - - /*! - * \brief Returns the activity coefficient of a component in a - * phase. - * - * We define the activity coefficent \f$\gamma_{\alpha,\kappa}\f$ - * of component \f$\kappa\f$ by the following equation: - * \f[ f_\kappa = p_\alpha \gamma_{\alpha,\kappa} \f] - * where \f$f_\kappa\f$ is the component's fugacity and \f$p_\alpha\f$ - * is the phase' pressure - * - * For liquids with very low miscibility this boils down to the - * inverse Henry constant for the solutes and the partial pressure - * for the solvent. - * - * For ideal gases this is equivalent to the gas pressure, in real - * gases it is the gas pressure times the component's fugacity - * coefficient. - */ - template - static Scalar activityCoeff(int phaseIdx, - int compIdx, - Scalar temperature, - Scalar pressure, - const FluidState &state) - { - throw std::logic_error("activityCoeff() not implemented."); - return 0.0; - } - - /*! - * \brief Given a phase's composition, temperature and pressure, - * return the binary diffusion coefficent for components - * \f$i\f$ and \f$j\f$ in this phase. - */ - template - static Scalar diffCoeff(int phaseIdx, - int compIIdx, - int compJIdx, - Scalar temperature, - Scalar pressure, - const FluidState &fluidState) - { - throw std::logic_error("diffCoeff() not implemented."); - return 0.0; - } - - /*! - * \brief Given a phase's composition, temperature and pressure, - * return its specific enthalpy [J/kg]. - */ - template - static Scalar phaseEnthalpy(int phaseIdx, - Scalar temperature, - Scalar pressure, - const FluidState &fluidState) - { - throw std::logic_error("phaseEnthalpy() not implemented."); - return 0.0; - } - - /*! - * \brief Given a phase's composition, temperature and pressure, - * return its specific internal energy [J/kg]. - */ - template - static Scalar phaseInternalEnergy(int phaseIdx, - Scalar temperature, - Scalar pressure, - const FluidState &fluidState) - { - throw std::logic_error("phaseInternalEnergy() not implemented."); - return 0.0; - } - -private: - - static Params& params() - { - static Params params; // \TODO: Replace singleton here by something more thread-robust? - return params; - } -}; - -} // namespace Opm - -#endif // OPM_FLUIDSYSTEMBLACKOIL_HEADER_INCLUDED From 6138255d422a3bdf5c829efaf2708023b83805ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 29 Jun 2011 14:50:57 +0200 Subject: [PATCH 098/113] Removed unused class FluidSystemBlackoil. --- dune/porsol/blackoil/test/bo_fluid_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/dune/porsol/blackoil/test/bo_fluid_test.cpp index 5d3d5ea4..d42a1660 100644 --- a/dune/porsol/blackoil/test/bo_fluid_test.cpp +++ b/dune/porsol/blackoil/test/bo_fluid_test.cpp @@ -20,7 +20,6 @@ #include "config.h" #include -#include #include #include @@ -51,7 +50,4 @@ int main(int argc, char** argv) std::cout << s[Law::Liquid] << " " << kr << '\n'; } - // Test the FluidSystemBlackoil class. - Opm::FluidSystemBlackoil<> fluid_system; - fluid_system.init(parser); } From 409c2751316cc16a543fc8f3ecb3c4b2d2e407f0 Mon Sep 17 00:00:00 2001 From: convert-repo <> Date: Wed, 21 Dec 2011 11:21:09 +0000 Subject: [PATCH 099/113] update tags --- .hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 .hgtags diff --git a/.hgtags b/.hgtags new file mode 100644 index 00000000..df0776bb --- /dev/null +++ b/.hgtags @@ -0,0 +1 @@ +b3cc85c2b5ab3f5b283244624d06a1afab9f8d67 Version-InitialImport-svn935 From 7c0998e1975d668935bd8a8e9b3ab292a87f29f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 21 Dec 2011 13:09:12 +0100 Subject: [PATCH 100/113] Moved blackoil fluid classes to their proper place. --- {dune/porsol/blackoil => opm/core/fluid}/BlackoilFluid.hpp | 0 .../fluid => opm/core/fluid/blackoil}/BlackoilComponent.hpp | 0 .../blackoil/fluid => opm/core/fluid/blackoil}/BlackoilDefs.hpp | 0 .../blackoil/fluid => opm/core/fluid/blackoil}/BlackoilPVT.cpp | 0 .../blackoil/fluid => opm/core/fluid/blackoil}/BlackoilPVT.hpp | 0 .../core/fluid/blackoil}/FluidMatrixInteractionBlackoil.hpp | 0 .../fluid => opm/core/fluid/blackoil}/FluidStateBlackoil.hpp | 0 .../porsol/blackoil/fluid => opm/core/fluid/blackoil}/Makefile.am | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityDead.cpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityDead.hpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityLiveGas.cpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityLiveGas.hpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityLiveOil.cpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityLiveOil.hpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityProps.cpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityProps.hpp | 0 .../fluid => opm/core/fluid/blackoil}/MiscibilityWater.hpp | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename {dune/porsol/blackoil => opm/core/fluid}/BlackoilFluid.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/BlackoilComponent.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/BlackoilDefs.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/BlackoilPVT.cpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/BlackoilPVT.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/FluidMatrixInteractionBlackoil.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/FluidStateBlackoil.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/Makefile.am (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityDead.cpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityDead.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityLiveGas.cpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityLiveGas.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityLiveOil.cpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityLiveOil.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityProps.cpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityProps.hpp (100%) rename {dune/porsol/blackoil/fluid => opm/core/fluid/blackoil}/MiscibilityWater.hpp (100%) diff --git a/dune/porsol/blackoil/BlackoilFluid.hpp b/opm/core/fluid/BlackoilFluid.hpp similarity index 100% rename from dune/porsol/blackoil/BlackoilFluid.hpp rename to opm/core/fluid/BlackoilFluid.hpp diff --git a/dune/porsol/blackoil/fluid/BlackoilComponent.hpp b/opm/core/fluid/blackoil/BlackoilComponent.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/BlackoilComponent.hpp rename to opm/core/fluid/blackoil/BlackoilComponent.hpp diff --git a/dune/porsol/blackoil/fluid/BlackoilDefs.hpp b/opm/core/fluid/blackoil/BlackoilDefs.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/BlackoilDefs.hpp rename to opm/core/fluid/blackoil/BlackoilDefs.hpp diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.cpp b/opm/core/fluid/blackoil/BlackoilPVT.cpp similarity index 100% rename from dune/porsol/blackoil/fluid/BlackoilPVT.cpp rename to opm/core/fluid/blackoil/BlackoilPVT.cpp diff --git a/dune/porsol/blackoil/fluid/BlackoilPVT.hpp b/opm/core/fluid/blackoil/BlackoilPVT.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/BlackoilPVT.hpp rename to opm/core/fluid/blackoil/BlackoilPVT.hpp diff --git a/dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp b/opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/FluidMatrixInteractionBlackoil.hpp rename to opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp diff --git a/dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp b/opm/core/fluid/blackoil/FluidStateBlackoil.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/FluidStateBlackoil.hpp rename to opm/core/fluid/blackoil/FluidStateBlackoil.hpp diff --git a/dune/porsol/blackoil/fluid/Makefile.am b/opm/core/fluid/blackoil/Makefile.am similarity index 100% rename from dune/porsol/blackoil/fluid/Makefile.am rename to opm/core/fluid/blackoil/Makefile.am diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.cpp b/opm/core/fluid/blackoil/MiscibilityDead.cpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityDead.cpp rename to opm/core/fluid/blackoil/MiscibilityDead.cpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityDead.hpp b/opm/core/fluid/blackoil/MiscibilityDead.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityDead.hpp rename to opm/core/fluid/blackoil/MiscibilityDead.hpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp b/opm/core/fluid/blackoil/MiscibilityLiveGas.cpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityLiveGas.cpp rename to opm/core/fluid/blackoil/MiscibilityLiveGas.cpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp b/opm/core/fluid/blackoil/MiscibilityLiveGas.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityLiveGas.hpp rename to opm/core/fluid/blackoil/MiscibilityLiveGas.hpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp b/opm/core/fluid/blackoil/MiscibilityLiveOil.cpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityLiveOil.cpp rename to opm/core/fluid/blackoil/MiscibilityLiveOil.cpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp b/opm/core/fluid/blackoil/MiscibilityLiveOil.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityLiveOil.hpp rename to opm/core/fluid/blackoil/MiscibilityLiveOil.hpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.cpp b/opm/core/fluid/blackoil/MiscibilityProps.cpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityProps.cpp rename to opm/core/fluid/blackoil/MiscibilityProps.cpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityProps.hpp b/opm/core/fluid/blackoil/MiscibilityProps.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityProps.hpp rename to opm/core/fluid/blackoil/MiscibilityProps.hpp diff --git a/dune/porsol/blackoil/fluid/MiscibilityWater.hpp b/opm/core/fluid/blackoil/MiscibilityWater.hpp similarity index 100% rename from dune/porsol/blackoil/fluid/MiscibilityWater.hpp rename to opm/core/fluid/blackoil/MiscibilityWater.hpp From cbe5d3015bce2c5f811cc3a31fb5272f7b9ea514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 21 Dec 2011 13:22:26 +0100 Subject: [PATCH 101/113] Work in progress on adapting to opm-core. --- Makefile.am | 5 +++++ opm/core/fluid/blackoil/BlackoilDefs.hpp | 15 +++++++++------ opm/core/fluid/blackoil/BlackoilPVT.hpp | 6 +++--- opm/core/fluid/blackoil/MiscibilityDead.cpp | 8 ++++---- opm/core/fluid/blackoil/MiscibilityDead.hpp | 4 ++-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index b5b51687..30ce198d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,6 +9,11 @@ lib_LTLIBRARIES = libopmcore.la libopmcore_la_SOURCES = \ opm/core/eclipse/EclipseGridInspector.cpp \ opm/core/eclipse/EclipseGridParser.cpp \ +opm/core/fluid/blackoil/BlackoilPVT.cpp \ +opm/core/fluid/blackoil/MiscibilityDead.cpp \ +opm/core/fluid/blackoil/MiscibilityLiveGas.cpp \ +opm/core/fluid/blackoil/MiscibilityLiveOil.cpp \ +opm/core/fluid/blackoil/MiscibilityProps.cpp \ opm/core/utility/MonotCubicInterpolator.cpp \ opm/core/utility/parameters/Parameter.cpp \ opm/core/utility/parameters/ParameterGroup.cpp \ diff --git a/opm/core/fluid/blackoil/BlackoilDefs.hpp b/opm/core/fluid/blackoil/BlackoilDefs.hpp index e6e4afcb..7615c5e6 100644 --- a/opm/core/fluid/blackoil/BlackoilDefs.hpp +++ b/opm/core/fluid/blackoil/BlackoilDefs.hpp @@ -21,8 +21,7 @@ #define OPM_BLACKOILDEFS_HEADER_INCLUDED -#include -#include +#include #include namespace Opm @@ -38,11 +37,15 @@ namespace Opm enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; typedef double Scalar; - typedef Dune::FieldVector CompVec; - typedef Dune::FieldVector PhaseVec; +// typedef Dune::FieldVector CompVec; +// typedef Dune::FieldVector PhaseVec; + typedef std::tr1::array CompVec; + typedef std::tr1::array PhaseVec; BOOST_STATIC_ASSERT(int(numComponents) == int(numPhases)); - typedef Dune::FieldMatrix PhaseToCompMatrix; - typedef Dune::FieldMatrix PhaseJacobian; +// typedef Dune::FieldMatrix PhaseToCompMatrix; +// typedef Dune::FieldMatrix PhaseJacobian; + typedef std::tr1::array PhaseToCompMatrix; + typedef std::tr1::array PhaseJacobian; }; } // namespace Opm diff --git a/opm/core/fluid/blackoil/BlackoilPVT.hpp b/opm/core/fluid/blackoil/BlackoilPVT.hpp index d5469223..92ca25c7 100644 --- a/opm/core/fluid/blackoil/BlackoilPVT.hpp +++ b/opm/core/fluid/blackoil/BlackoilPVT.hpp @@ -21,9 +21,9 @@ #define OPM_BLACKOILPVT_HEADER_INCLUDED -#include "MiscibilityProps.hpp" -#include "BlackoilDefs.hpp" -#include +#include +#include +#include #include #include diff --git a/opm/core/fluid/blackoil/MiscibilityDead.cpp b/opm/core/fluid/blackoil/MiscibilityDead.cpp index c92b2abf..2a490ef2 100644 --- a/opm/core/fluid/blackoil/MiscibilityDead.cpp +++ b/opm/core/fluid/blackoil/MiscibilityDead.cpp @@ -28,11 +28,11 @@ along with OPM. If not, see . */ +#include #include -#include "MiscibilityDead.hpp" -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/opm/core/fluid/blackoil/MiscibilityDead.hpp b/opm/core/fluid/blackoil/MiscibilityDead.hpp index 8962bd58..f6f1a96e 100644 --- a/opm/core/fluid/blackoil/MiscibilityDead.hpp +++ b/opm/core/fluid/blackoil/MiscibilityDead.hpp @@ -35,8 +35,8 @@ * Detailed description. */ -#include "MiscibilityProps.hpp" -#include +#include +#include namespace Opm { From a55b664eb962b4cfd7202a5bd2da7efc2f683dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 21 Dec 2011 13:29:15 +0100 Subject: [PATCH 102/113] Now fluid cpp files compile successfully. --- opm/core/fluid/blackoil/BlackoilPVT.cpp | 18 +++++++++--------- opm/core/fluid/blackoil/MiscibilityLiveGas.cpp | 6 +++--- opm/core/fluid/blackoil/MiscibilityLiveOil.cpp | 8 ++++---- opm/core/fluid/blackoil/MiscibilityWater.hpp | 4 ++-- .../core/utility}/UniformTableLinear.hpp | 4 ++-- .../utility}/buildUniformMonotoneTable.hpp | 4 ++-- .../core/utility}/linearInterpolation.hpp | 0 7 files changed, 22 insertions(+), 22 deletions(-) rename {dune/porsol/common => opm/core/utility}/UniformTableLinear.hpp (98%) rename {dune/porsol/common => opm/core/utility}/buildUniformMonotoneTable.hpp (94%) rename {dune/porsol/common => opm/core/utility}/linearInterpolation.hpp (100%) diff --git a/opm/core/fluid/blackoil/BlackoilPVT.cpp b/opm/core/fluid/blackoil/BlackoilPVT.cpp index c35029f0..076116a8 100644 --- a/opm/core/fluid/blackoil/BlackoilPVT.cpp +++ b/opm/core/fluid/blackoil/BlackoilPVT.cpp @@ -18,15 +18,15 @@ */ -#include "BlackoilPVT.hpp" -#include -#include -#include "MiscibilityDead.hpp" -#include "MiscibilityLiveOil.hpp" -#include "MiscibilityLiveGas.hpp" -#include "MiscibilityWater.hpp" -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace Dune; diff --git a/opm/core/fluid/blackoil/MiscibilityLiveGas.cpp b/opm/core/fluid/blackoil/MiscibilityLiveGas.cpp index 3d44239a..6e101277 100644 --- a/opm/core/fluid/blackoil/MiscibilityLiveGas.cpp +++ b/opm/core/fluid/blackoil/MiscibilityLiveGas.cpp @@ -29,10 +29,10 @@ */ +#include #include -#include "MiscibilityLiveGas.hpp" -#include -#include +#include +#include using namespace std; using namespace Dune; diff --git a/opm/core/fluid/blackoil/MiscibilityLiveOil.cpp b/opm/core/fluid/blackoil/MiscibilityLiveOil.cpp index 4b9fbe33..60a67a1f 100644 --- a/opm/core/fluid/blackoil/MiscibilityLiveOil.cpp +++ b/opm/core/fluid/blackoil/MiscibilityLiveOil.cpp @@ -28,10 +28,10 @@ along with OPM. If not, see . */ +#include +#include +#include #include -#include "MiscibilityLiveOil.hpp" -#include -#include using namespace std; using namespace Dune; @@ -85,7 +85,7 @@ namespace Opm while (undersat_oil_tables_[iNext][0].size() < 2) { ++iNext; } - assert(iNext < sz); + ASSERT(iNext < sz); for (int i=0; i 1) { iPrev = i; diff --git a/opm/core/fluid/blackoil/MiscibilityWater.hpp b/opm/core/fluid/blackoil/MiscibilityWater.hpp index 2082daa0..0075f059 100644 --- a/opm/core/fluid/blackoil/MiscibilityWater.hpp +++ b/opm/core/fluid/blackoil/MiscibilityWater.hpp @@ -34,8 +34,8 @@ #ifndef OPENRS_MISCIBILITYWATER_HEADER #define OPENRS_MISCIBILITYWATER_HEADER -#include "MiscibilityProps.hpp" -#include +#include +#include // Forward declaration. class PVTW; diff --git a/dune/porsol/common/UniformTableLinear.hpp b/opm/core/utility/UniformTableLinear.hpp similarity index 98% rename from dune/porsol/common/UniformTableLinear.hpp rename to opm/core/utility/UniformTableLinear.hpp index cf3bef25..c8840770 100644 --- a/dune/porsol/common/UniformTableLinear.hpp +++ b/opm/core/utility/UniformTableLinear.hpp @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include namespace Dune { namespace utils { diff --git a/dune/porsol/common/buildUniformMonotoneTable.hpp b/opm/core/utility/buildUniformMonotoneTable.hpp similarity index 94% rename from dune/porsol/common/buildUniformMonotoneTable.hpp rename to opm/core/utility/buildUniformMonotoneTable.hpp index 03c060be..09501f9a 100644 --- a/dune/porsol/common/buildUniformMonotoneTable.hpp +++ b/opm/core/utility/buildUniformMonotoneTable.hpp @@ -20,8 +20,8 @@ #ifndef OPM_BUILDUNIFORMMONOTONETABLE_HEADER_INCLUDED #define OPM_BUILDUNIFORMMONOTONETABLE_HEADER_INCLUDED -#include -#include +#include +#include namespace Dune { namespace utils { diff --git a/dune/porsol/common/linearInterpolation.hpp b/opm/core/utility/linearInterpolation.hpp similarity index 100% rename from dune/porsol/common/linearInterpolation.hpp rename to opm/core/utility/linearInterpolation.hpp From 7d705bb763e89f7474ec6e81a531648f4051a09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 10:40:43 +0100 Subject: [PATCH 103/113] Moved tests to proper place. --- {dune/porsol/blackoil/test => tests}/bo_fluid_p_and_z_deps.cpp | 0 {dune/porsol/blackoil/test => tests}/bo_fluid_pressuredeps.cpp | 0 {dune/porsol/blackoil/test => tests}/bo_fluid_test.cpp | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {dune/porsol/blackoil/test => tests}/bo_fluid_p_and_z_deps.cpp (100%) rename {dune/porsol/blackoil/test => tests}/bo_fluid_pressuredeps.cpp (100%) rename {dune/porsol/blackoil/test => tests}/bo_fluid_test.cpp (100%) diff --git a/dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp b/tests/bo_fluid_p_and_z_deps.cpp similarity index 100% rename from dune/porsol/blackoil/test/bo_fluid_p_and_z_deps.cpp rename to tests/bo_fluid_p_and_z_deps.cpp diff --git a/dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp b/tests/bo_fluid_pressuredeps.cpp similarity index 100% rename from dune/porsol/blackoil/test/bo_fluid_pressuredeps.cpp rename to tests/bo_fluid_pressuredeps.cpp diff --git a/dune/porsol/blackoil/test/bo_fluid_test.cpp b/tests/bo_fluid_test.cpp similarity index 100% rename from dune/porsol/blackoil/test/bo_fluid_test.cpp rename to tests/bo_fluid_test.cpp From 9b2bfe40d3d4dd4f986d11e8ce6b8a9e75b04ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 12:59:42 +0100 Subject: [PATCH 104/113] Blackoil fluid test programs now compile. --- opm/core/fluid/BlackoilFluid.hpp | 52 ++++-- opm/core/fluid/blackoil/BlackoilComponent.hpp | 165 ------------------ opm/core/fluid/blackoil/BlackoilDefs.hpp | 64 ++++++- .../FluidMatrixInteractionBlackoil.hpp | 8 +- .../fluid/blackoil/FluidStateBlackoil.hpp | 8 +- opm/core/fluid/blackoil/MiscibilityDead.cpp | 4 +- tests/Makefile.am | 6 + tests/bo_fluid_p_and_z_deps.cpp | 12 +- tests/bo_fluid_pressuredeps.cpp | 87 +++++---- tests/bo_fluid_test.cpp | 10 +- 10 files changed, 178 insertions(+), 238 deletions(-) delete mode 100644 opm/core/fluid/blackoil/BlackoilComponent.hpp diff --git a/opm/core/fluid/BlackoilFluid.hpp b/opm/core/fluid/BlackoilFluid.hpp index d1cd6df2..6aa3142d 100644 --- a/opm/core/fluid/BlackoilFluid.hpp +++ b/opm/core/fluid/BlackoilFluid.hpp @@ -21,11 +21,10 @@ #define OPM_BLACKOILFLUID_HEADER_INCLUDED -#include -#include -#include -#include -#include +#include +#include +#include +#include #include @@ -174,26 +173,34 @@ namespace Opm states.phase_volume_density.resize(num); states.total_phase_volume_density.resize(num); states.saturation.resize(num); +#ifdef COMPUTE_OLD_TERMS states.phase_compressibility.resize(num); states.total_compressibility.resize(num); states.experimental_term.resize(num); +#endif #pragma omp parallel for for (int i = 0; i < num; ++i) { const CompVec& z = states.surface_volume_density[i]; const PhaseVec& B = states.formation_volume_factor[i]; - const PhaseVec& dB = states.formation_volume_factor_deriv[i]; const PhaseVec& R = states.solution_factor[i]; - const PhaseVec& dR = states.solution_factor_deriv[i]; PhaseToCompMatrix& At = states.state_matrix[i]; PhaseVec& u = states.phase_volume_density[i]; double& tot_phase_vol_dens = states.total_phase_volume_density[i]; PhaseVec& s = states.saturation[i]; +#ifdef COMPUTE_OLD_TERMS + const PhaseVec& dB = states.formation_volume_factor_deriv[i]; + const PhaseVec& dR = states.solution_factor_deriv[i]; PhaseVec& cp = states.phase_compressibility[i]; double& tot_comp = states.total_compressibility[i]; double& exp_term = states.experimental_term[i]; computeSingleEquilibrium(B, dB, R, dR, z, At, u, tot_phase_vol_dens, s, cp, tot_comp, exp_term); +#else + computeSingleEquilibrium(B, R, z, + At, u, tot_phase_vol_dens, + s); +#endif } } @@ -276,6 +283,13 @@ namespace Opm R[Aqua] = 0.0; R[Vapour] = pvt_.R(p[Vapour], z, Vapour); R[Liquid] = pvt_.R(p[Liquid], z, Liquid); + + // Convenience vars. + PhaseToCompMatrix& At = fluid_state.phase_to_comp_; + PhaseVec& u = fluid_state.phase_volume_density_; + double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_; + PhaseVec& s = fluid_state.saturation_; +#ifdef COMPUTE_OLD_TERMS PhaseVec dB; dB[Aqua] = pvt_.dBdp(p[Aqua], z, Aqua); dB[Vapour] = pvt_.dBdp(p[Vapour], z, Vapour); @@ -284,19 +298,17 @@ namespace Opm dR[Aqua] = 0.0; dR[Vapour] = pvt_.dRdp(p[Vapour], z, Vapour); dR[Liquid] = pvt_.dRdp(p[Liquid], z, Liquid); - - // Convenience vars. - PhaseToCompMatrix& At = fluid_state.phase_to_comp_; - PhaseVec& u = fluid_state.phase_volume_density_; - double& tot_phase_vol_dens = fluid_state.total_phase_volume_density_; - PhaseVec& s = fluid_state.saturation_; PhaseVec& cp = fluid_state.phase_compressibility_; double& tot_comp = fluid_state.total_compressibility_; double& exp_term = fluid_state.experimental_term_; - computeSingleEquilibrium(B, dB, R, dR, z, At, u, tot_phase_vol_dens, s, cp, tot_comp, exp_term); +#else + computeSingleEquilibrium(B, R, z, + At, u, tot_phase_vol_dens, + s); +#endif // Compute viscosities. PhaseVec& mu = fluid_state.viscosity_; @@ -307,6 +319,7 @@ namespace Opm +#ifdef COMPUTE_OLD_TERMS static void computeSingleEquilibrium(const PhaseVec& B, const PhaseVec& dB, const PhaseVec& R, @@ -319,6 +332,15 @@ namespace Opm PhaseVec& cp, double& tot_comp, double& exp_term) +#else + static void computeSingleEquilibrium(const PhaseVec& B, + const PhaseVec& R, + const CompVec& z, + PhaseToCompMatrix& At, + PhaseVec& u, + double& tot_phase_vol_dens, + PhaseVec& s) +#endif { // Set the A matrix (A = RB^{-1}) // Using At since we really want Fortran ordering @@ -345,6 +367,7 @@ namespace Opm s[phase] = u[phase]/tot_phase_vol_dens; } +#ifdef COMPUTE_OLD_TERMS // Phase compressibilities. // PhaseVec& cp = fluid_state.phase_compressibility_[i]; // Set the derivative of the A matrix (A = RB^{-1}) @@ -372,6 +395,7 @@ namespace Opm dAt.mtv(tmp1, tmp2); Ait.mtv(tmp2, tmp3); exp_term = tmp3[Aqua] + tmp3[Liquid] + tmp3[Gas]; +#endif } diff --git a/opm/core/fluid/blackoil/BlackoilComponent.hpp b/opm/core/fluid/blackoil/BlackoilComponent.hpp deleted file mode 100644 index 61294a68..00000000 --- a/opm/core/fluid/blackoil/BlackoilComponent.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright 2010 SINTEF ICT, Applied Mathematics. - - 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_BLACKOILCOMPONENT_HEADER_INCLUDED -#define OPM_BLACKOILCOMPONENT_HEADER_INCLUDED - - -#include - -namespace Dumux -{ - -/*! - * \ingroup Components - - * \brief - * A component class for the black oil model, intended to be used - * for all three components. - * - * \tparam Scalar The type used for scalar values - */ -template -class BlackoilComponent -{ -public: - /*! - * \brief A human readable name for the component. - */ - static const char *name() - { - return "BlackoilComponent"; - } - - /*! - * \brief The molar mass in [kg] of the component. - */ - static Scalar molarMass() - { DUNE_THROW(Dune::NotImplemented, "Component::molarMass()"); } - - /*! - * \brief Returns the critical temperature in [K] of the component. - */ - static Scalar criticalTemperature() - { DUNE_THROW(Dune::NotImplemented, "Component::criticalTemperature()"); } - - /*! - * \brief Returns the critical pressure in [Pa] of the component. - */ - static Scalar criticalPressure() - { DUNE_THROW(Dune::NotImplemented, "Component::criticalPressure()"); } - - /*! - * \brief Returns the temperature in [K] at the component's triple point. - */ - static Scalar tripleTemperature() - { DUNE_THROW(Dune::NotImplemented, "Component::tripleTemperature()"); } - - /*! - * \brief Returns the pressure in [Pa] at the component's triple point. - */ - static Scalar triplePressure() - { DUNE_THROW(Dune::NotImplemented, "Component::triplePressure()"); } - - /*! - * \brief The vapor pressure in [Pa] of the component at a given - * temperature in [K]. - * - * \param T temperature of the component in [K] - */ - static Scalar vaporPressure(Scalar T) - { DUNE_THROW(Dune::NotImplemented, "Component::vaporPressure()"); } - - /*! - * \brief The density in [kg/m^3] of the component at a given pressure in [Pa] and temperature in [K]. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static Scalar gasDensity(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::density()"); } - - /*! - * \brief The density [kg/m^3] of the liquid component at a given pressure in [Pa] and temperature in [K]. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static Scalar liquidDensity(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::density()"); } - - /*! - * \brief Specific enthalpy [J/kg] of the pure component in gas. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static const Scalar gasEnthalpy(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::gasEnthalpy()"); } - - /*! - * \brief Specific enthalpy [J/kg] of the pure component in liquid. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static const Scalar liquidEnthalpy(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::liquidEnthalpy()"); } - - /*! - * \brief Specific internal energy [J/kg] of the pure component in gas. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static const Scalar gasInternalEnergy(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::gasInternalEnergy()"); } - - /*! - * \brief Specific internal energy [J/kg] of pure the pure component in liquid. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static const Scalar liquidInternalEnergy(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::liquidInternalEnergy()"); } - - /*! - * \brief The dynamic viscosity [Pa*s] of the pure component at a given pressure in [Pa] and temperature in [K]. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static Scalar gasViscosity(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::gasViscosity()"); } - - /*! - * \brief The dynamic liquid viscosity [Pa*s] of the pure component. - * - * \param temperature temperature of component in [K] - * \param pressure pressure of component in [Pa] - */ - static Scalar liquidViscosity(Scalar temperature, Scalar pressure) - { DUNE_THROW(Dune::NotImplemented, "Component::liquidViscosity()"); } - -}; - -} // end namepace - -#endif // OPM_BLACKOILCOMPONENT_HEADER_INCLUDED diff --git a/opm/core/fluid/blackoil/BlackoilDefs.hpp b/opm/core/fluid/blackoil/BlackoilDefs.hpp index 7615c5e6..fba7546c 100644 --- a/opm/core/fluid/blackoil/BlackoilDefs.hpp +++ b/opm/core/fluid/blackoil/BlackoilDefs.hpp @@ -22,6 +22,7 @@ #include +#include #include namespace Opm @@ -36,16 +37,63 @@ namespace Opm enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 }; enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2 }; + // We need types with operator= and constructor taking scalars + // for the small vectors and matrices, to save us from having to + // rewrite a large amount of code. + template + class SmallVec + { + public: + SmallVec() + {} + SmallVec(const T& elem) + { data_.assign(elem); } // In C++11, assign -> fill + SmallVec& operator=(const T& elem) + { data_.assign(elem); return *this; } + const T& operator[](int i) const + { return data_[i]; } + T& operator[](int i) + { return data_[i]; } + template + void assign(const U& elem) + { + for (int i = 0; i < N; ++i) { + data_[i] = elem; + } + } + private: + std::tr1::array data_; + }; + template + class SmallMat + { + public: + SmallMat() + {} + SmallMat(const T& elem) + { data_.assign(elem); } // In C++11, assign -> fill + SmallMat& operator=(const T& elem) + { data_.assign(elem); return *this; } + typedef SmallVec RowType; + const RowType& operator[](int i) const + { return data_[i]; } + RowType& operator[](int i) + { return data_[i]; } + private: + SmallVec data_; + }; + typedef double Scalar; -// typedef Dune::FieldVector CompVec; -// typedef Dune::FieldVector PhaseVec; - typedef std::tr1::array CompVec; - typedef std::tr1::array PhaseVec; + typedef SmallVec CompVec; + typedef SmallVec PhaseVec; BOOST_STATIC_ASSERT(int(numComponents) == int(numPhases)); -// typedef Dune::FieldMatrix PhaseToCompMatrix; -// typedef Dune::FieldMatrix PhaseJacobian; - typedef std::tr1::array PhaseToCompMatrix; - typedef std::tr1::array PhaseJacobian; + typedef SmallMat PhaseToCompMatrix; + typedef SmallMat PhaseJacobian; + // Attempting to guard against alignment issues. + BOOST_STATIC_ASSERT(sizeof(CompVec) == numComponents*sizeof(Scalar)); + BOOST_STATIC_ASSERT(sizeof(PhaseVec) == numPhases*sizeof(Scalar)); + BOOST_STATIC_ASSERT(sizeof(PhaseToCompMatrix) == numComponents*numPhases*sizeof(Scalar)); + BOOST_STATIC_ASSERT(sizeof(PhaseJacobian) == numPhases*numPhases*sizeof(Scalar)); }; } // namespace Opm diff --git a/opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp b/opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp index cd323f06..b03f4700 100644 --- a/opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp +++ b/opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp @@ -20,10 +20,10 @@ #ifndef OPM_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED #define OPM_FLUIDMATRIXINTERACTIONBLACKOIL_HEADER_INCLUDED -#include -#include -#include -#include "BlackoilDefs.hpp" +#include +#include +#include +#include #include #include diff --git a/opm/core/fluid/blackoil/FluidStateBlackoil.hpp b/opm/core/fluid/blackoil/FluidStateBlackoil.hpp index dfc8a17b..fd96edb3 100644 --- a/opm/core/fluid/blackoil/FluidStateBlackoil.hpp +++ b/opm/core/fluid/blackoil/FluidStateBlackoil.hpp @@ -40,9 +40,11 @@ namespace Opm PhaseVec solution_factor_; PhaseToCompMatrix phase_to_comp_; // RB^{-1} in Fortran ordering PhaseVec saturation_; +#ifdef COMPUTE_OLD_TERMS PhaseVec phase_compressibility_; Scalar total_compressibility_; Scalar experimental_term_; +#endif PhaseVec viscosity_; PhaseVec relperm_; PhaseJacobian drelperm_; @@ -62,9 +64,7 @@ namespace Opm // Variables from PVT functions. std::vector formation_volume_factor; // B - std::vector formation_volume_factor_deriv; // dB/dp std::vector solution_factor; // R - std::vector solution_factor_deriv; // dR/dp std::vector viscosity; // mu // Variables computed from PVT data. @@ -74,9 +74,13 @@ namespace Opm std::vector phase_volume_density; // u std::vector total_phase_volume_density; // sum(u) std::vector saturation; // s = u/sum(u) +#ifdef COMPUTE_OLD_TERMS + std::vector formation_volume_factor_deriv; // dB/dp + std::vector solution_factor_deriv; // dR/dp std::vector phase_compressibility; // c std::vector total_compressibility; // cT std::vector experimental_term; // ex = sum(Ai*dA*Ai*z) +#endif // Variables computed from saturation. std::vector relperm; // kr diff --git a/opm/core/fluid/blackoil/MiscibilityDead.cpp b/opm/core/fluid/blackoil/MiscibilityDead.cpp index 2a490ef2..eeeddb46 100644 --- a/opm/core/fluid/blackoil/MiscibilityDead.cpp +++ b/opm/core/fluid/blackoil/MiscibilityDead.cpp @@ -82,7 +82,7 @@ namespace Opm { } - double MiscibilityDead::getViscosity(int region, double press, const surfvol_t& /*surfvol*/) const + double MiscibilityDead::getViscosity(int /*region*/, double press, const surfvol_t& /*surfvol*/) const { return viscosity_(press); } @@ -100,7 +100,7 @@ namespace Opm } } - double MiscibilityDead::B(int region, double press, const surfvol_t& /*surfvol*/) const + double MiscibilityDead::B(int /*region*/, double press, const surfvol_t& /*surfvol*/) const { // Interpolate 1/B return 1.0/one_over_B_(press); diff --git a/tests/Makefile.am b/tests/Makefile.am index 98a3822b..d7e5f9ce 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,6 +15,9 @@ $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) noinst_PROGRAMS = \ +bo_fluid_p_and_z_deps \ +bo_fluid_pressuredeps \ +bo_fluid_test \ monotcubicinterpolator_test \ param_test \ sparsetable_test \ @@ -23,6 +26,9 @@ unit_test \ test_readvector \ test_sf2p +bo_fluid_p_and_z_deps_SOURCES = bo_fluid_p_and_z_deps.cpp +bo_fluid_pressuredeps_SOURCES = bo_fluid_pressuredeps.cpp +bo_fluid_test_SOURCES = bo_fluid_test.cpp monotcubicinterpolator_test_SOURCES = monotcubicinterpolator_test.cpp param_test_SOURCES = param_test.cpp sparsetable_test_SOURCES = sparsetable_test.cpp diff --git a/tests/bo_fluid_p_and_z_deps.cpp b/tests/bo_fluid_p_and_z_deps.cpp index 3d1a5aaa..af3d69bc 100644 --- a/tests/bo_fluid_p_and_z_deps.cpp +++ b/tests/bo_fluid_p_and_z_deps.cpp @@ -20,9 +20,9 @@ #include "config.h" -#include -#include -#include +#include +#include +#include int main(int argc, char** argv) @@ -49,7 +49,11 @@ int main(int argc, char** argv) int changing_component = param.getDefault("changing_component", int(Opm::BlackoilFluid::Gas)); double min_z = param.getDefault("min_z", 0.0); double max_z = param.getDefault("max_z", 500.0); +#ifdef COMPUTE_OLD_TERMS int variable = param.getDefault("variable", 0); +#else + int variable = param.getDefault("variable", 2); +#endif Opm::BlackoilFluid::CompVec z = z0; std::cout << "%}\n" << "data = [\n"; @@ -67,12 +71,14 @@ int main(int argc, char** argv) std::cout.fill(' '); double var = 0.0; switch (variable) { +#ifdef COMPUTE_OLD_TERMS case 0: var = state.total_compressibility_; break; case 1: var = state.experimental_term_; break; +#endif case 2: var = state.saturation_[0]; break; diff --git a/tests/bo_fluid_pressuredeps.cpp b/tests/bo_fluid_pressuredeps.cpp index 1c6d1a44..7c277976 100644 --- a/tests/bo_fluid_pressuredeps.cpp +++ b/tests/bo_fluid_pressuredeps.cpp @@ -19,10 +19,51 @@ #include "config.h" -#include -#include -#include +#include +#include +#include +#ifdef COMPUTE_OLD_TERMS +void printCompressibilityTerms(double p, const Opm::BlackoilFluid::FluidState& state) +{ + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + std::cout << p << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_compressibility_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << totmob << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_phase_volume_density_ << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.experimental_term_ << '\n'; +} +#endif + +void printSatsEtc(double p, const Opm::BlackoilFluid::FluidState& state) +{ + std::cout.precision(6); + std::cout.width(15); + std::cout.fill(' '); + std::cout << p << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[0] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[1] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.saturation_[2] << " "; + std::cout.width(15); + std::cout.fill(' '); + std::cout << state.total_phase_volume_density_ << '\n'; +} int main(int argc, char** argv) { @@ -43,7 +84,9 @@ int main(int argc, char** argv) int num_pts = param.getDefault("num_pts", 41); double min_press = param.getDefault("min_press", 1e7); double max_press = param.getDefault("max_press", 3e7); +#ifdef COMPUTE_OLD_TERMS bool print_compr = param.getDefault("print_compr", true); +#endif for (int i = 0; i < num_pts; ++i) { double factor = double(i)/double(num_pts - 1); double p = (1.0 - factor)*min_press + factor*max_press; @@ -52,40 +95,14 @@ int main(int argc, char** argv) for (int phase = 0; phase < Opm::BlackoilFluid::numPhases; ++phase) { totmob += state.mobility_[phase]; } +#ifdef COMPUTE_OLD_TERMS if (print_compr) { - std::cout.precision(6); - std::cout.width(15); - std::cout.fill(' '); - std::cout << p << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.total_compressibility_ << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << totmob << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.total_phase_volume_density_ << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.experimental_term_ << '\n'; + printCompressibilityTerms(p, state); } else { - std::cout.precision(6); - std::cout.width(15); - std::cout.fill(' '); - std::cout << p << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.saturation_[0] << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.saturation_[1] << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.saturation_[2] << " "; - std::cout.width(15); - std::cout.fill(' '); - std::cout << state.total_phase_volume_density_ << '\n'; + printSatsEtc(p, state); } +#else + printSatsEtc(p, state); +#endif } } diff --git a/tests/bo_fluid_test.cpp b/tests/bo_fluid_test.cpp index d42a1660..019b58dc 100644 --- a/tests/bo_fluid_test.cpp +++ b/tests/bo_fluid_test.cpp @@ -19,9 +19,9 @@ #include "config.h" -#include -#include -#include +#include +#include +#include int main(int argc, char** argv) @@ -37,7 +37,7 @@ int main(int argc, char** argv) Opm::FluidMatrixInteractionBlackoilParams fluid_params; fluid_params.init(parser); typedef Opm::FluidMatrixInteractionBlackoil Law; - Dune::FieldVector s, kr; + Law::PhaseVec s, kr; const double temp = 300; // [K] int num = 41; for (int i = 0; i < num; ++i) { @@ -47,7 +47,7 @@ int main(int argc, char** argv) Law::kr(kr, fluid_params, s, temp); std::cout.width(6); std::cout.fill(' '); - std::cout << s[Law::Liquid] << " " << kr << '\n'; + std::cout << s[Law::Liquid] << " " << kr[0] << ' ' << kr[1] << ' ' << kr[2] << '\n'; } } From a1e851a2375640de3ed71aa4888a4d242f058826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 13:00:48 +0100 Subject: [PATCH 105/113] Ignoring test executables. --- .hgignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.hgignore b/.hgignore index 53e2d2a8..e684c047 100644 --- a/.hgignore +++ b/.hgignore @@ -37,3 +37,5 @@ tests/test_cfs_tpfa tests/test_jacsys tests/test_readvector tests/test_sf2p +tests/bo_fluid_p_and_z_deps +tests/bo_fluid_pressuredeps From 267486516c565d4dbf392a3450d98de719b7f1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 13:06:10 +0100 Subject: [PATCH 106/113] Added headers to makefile. --- Makefile.am | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 30ce198d..eff335f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,10 +67,20 @@ opm/core/eclipse/EclipseGridParser.hpp \ opm/core/eclipse/EclipseGridParserHelpers.hpp \ opm/core/eclipse/EclipseUnits.hpp \ opm/core/eclipse/SpecialEclipseFields.hpp \ +opm/core/fluid/BlackoilFluid.hpp \ +opm/core/fluid/SimpleFluid2p.hpp \ +opm/core/fluid/blackoil/BlackoilDefs.hpp \ +opm/core/fluid/blackoil/BlackoilPVT.hpp \ +opm/core/fluid/blackoil/FluidMatrixInteractionBlackoil.hpp \ +opm/core/fluid/blackoil/FluidStateBlackoil.hpp \ +opm/core/fluid/blackoil/MiscibilityDead.hpp \ +opm/core/fluid/blackoil/MiscibilityLiveGas.hpp \ +opm/core/fluid/blackoil/MiscibilityLiveOil.hpp \ +opm/core/fluid/blackoil/MiscibilityProps.hpp \ +opm/core/fluid/blackoil/MiscibilityWater.hpp \ opm/core/utility/Average.hpp \ opm/core/utility/ErrorMacros.hpp \ opm/core/utility/Factory.hpp \ -opm/core/utility/linInt.hpp \ opm/core/utility/MonotCubicInterpolator.hpp \ opm/core/utility/parameters/Parameter.hpp \ opm/core/utility/parameters/ParameterGroup.hpp \ @@ -84,7 +94,11 @@ opm/core/utility/RootFinders.hpp \ opm/core/utility/SparseTable.hpp \ opm/core/utility/SparseVector.hpp \ opm/core/utility/StopWatch.hpp \ +opm/core/utility/UniformTableLinear.hpp \ opm/core/utility/Units.hpp \ +opm/core/utility/buildUniformMonotoneTable.hpp \ +opm/core/utility/linInt.hpp \ +opm/core/utility/linearInterpolation.hpp \ opm/core/utility/cpgpreprocess/readvector.hpp \ opm/core/utility/cpgpreprocess/uniquepoints.h \ opm/core/utility/cpgpreprocess/preprocess.h \ @@ -98,7 +112,6 @@ opm/core/utility/cart_grid.h \ opm/core/well.h \ opm/core/linalg/sparse_sys.h \ opm/core/linalg/blas_lapack.h \ -opm/core/fluid/SimpleFluid2p.hpp \ opm/core/grid.h \ opm/core/GridAdapter.hpp \ opm/core/pressure/fsh.h \ From b86f8350237354d208d75b29d408527d81937b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 14:42:11 +0100 Subject: [PATCH 107/113] BOOST_CPPFLAGS must be available when compiling library. --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index cfe4a9b0..b65fb6f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,8 @@ ACLOCAL_AMFLAGS = -I m4 # Recurse to build examples after libraries SUBDIRS = . tests examples +CPPFLAGS += $(BOOST_CPPFLAGS) + # Declare libraries lib_LTLIBRARIES = libopmcore.la From 328353a9c2553d32e683dcb6e4d52b2b5235670d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 22 Dec 2011 14:43:23 +0100 Subject: [PATCH 108/113] Stop using std::tr1::array<> since it is padded (alignment) on gcc 4.1 (CentOS 5.7). --- opm/core/fluid/blackoil/BlackoilDefs.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/core/fluid/blackoil/BlackoilDefs.hpp b/opm/core/fluid/blackoil/BlackoilDefs.hpp index fba7546c..08e44cb8 100644 --- a/opm/core/fluid/blackoil/BlackoilDefs.hpp +++ b/opm/core/fluid/blackoil/BlackoilDefs.hpp @@ -47,9 +47,9 @@ namespace Opm SmallVec() {} SmallVec(const T& elem) - { data_.assign(elem); } // In C++11, assign -> fill + { assign(elem); } SmallVec& operator=(const T& elem) - { data_.assign(elem); return *this; } + { assign(elem); return *this; } const T& operator[](int i) const { return data_[i]; } T& operator[](int i) @@ -62,7 +62,7 @@ namespace Opm } } private: - std::tr1::array data_; + T data_[N]; }; template class SmallMat @@ -71,7 +71,7 @@ namespace Opm SmallMat() {} SmallMat(const T& elem) - { data_.assign(elem); } // In C++11, assign -> fill + { data_.assign(elem); } SmallMat& operator=(const T& elem) { data_.assign(elem); return *this; } typedef SmallVec RowType; From 97297687943f81de74dd90744e0de7c7509c7627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 23 Dec 2011 12:49:06 +0100 Subject: [PATCH 109/113] Now the libtool library will reference its dependencies. --- Makefile.am | 35 ++++++++++++++++++++--------------- examples/Makefile.am | 8 +------- tests/Makefile.am | 8 +------- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Makefile.am b/Makefile.am index b65fb6f9..0543f765 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,11 +4,16 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = . tests examples CPPFLAGS += $(BOOST_CPPFLAGS) +LIBS += $(BOOST_FILESYSTEM_LIB) \ + $(BOOST_SYSTEM_LIB) \ + $(BOOST_DATE_TIME_LIB) \ + $(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ + $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) # Declare libraries lib_LTLIBRARIES = libopmcore.la -libopmcore_la_SOURCES = \ +libopmcore_la_SOURCES = \ opm/core/eclipse/EclipseGridInspector.cpp \ opm/core/eclipse/EclipseGridParser.cpp \ opm/core/fluid/blackoil/BlackoilPVT.cpp \ @@ -25,21 +30,21 @@ opm/core/utility/parameters/tinyxml/tinystr.cpp \ opm/core/utility/parameters/tinyxml/tinyxml.cpp \ opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp \ opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp \ -opm/core/utility/cart_grid.c \ -opm/core/utility/cpgpreprocess/geometry.c \ -opm/core/utility/cpgpreprocess/preprocess.c \ -opm/core/utility/cpgpreprocess/readvector.cpp \ -opm/core/utility/cpgpreprocess/cgridinterface.c \ -opm/core/utility/cpgpreprocess/sparsetable.c \ -opm/core/utility/cpgpreprocess/facetopology.c \ -opm/core/utility/cpgpreprocess/uniquepoints.c \ +opm/core/utility/cart_grid.c \ +opm/core/utility/cpgpreprocess/geometry.c \ +opm/core/utility/cpgpreprocess/preprocess.c \ +opm/core/utility/cpgpreprocess/readvector.cpp \ +opm/core/utility/cpgpreprocess/cgridinterface.c \ +opm/core/utility/cpgpreprocess/sparsetable.c \ +opm/core/utility/cpgpreprocess/facetopology.c \ +opm/core/utility/cpgpreprocess/uniquepoints.c \ opm/core/utility/StopWatch.cpp \ -opm/core/linalg/sparse_sys.c \ -opm/core/pressure/cfsh.c \ -opm/core/pressure/flow_bc.c \ -opm/core/pressure/well.c \ -opm/core/pressure/fsh_common_impl.c \ -opm/core/pressure/fsh.c \ +opm/core/linalg/sparse_sys.c \ +opm/core/pressure/cfsh.c \ +opm/core/pressure/flow_bc.c \ +opm/core/pressure/well.c \ +opm/core/pressure/fsh_common_impl.c \ +opm/core/pressure/fsh.c \ opm/core/pressure/tpfa/ifs_tpfa.c \ opm/core/pressure/tpfa/compr_source.c \ opm/core/pressure/tpfa/cfs_tpfa.c \ diff --git a/examples/Makefile.am b/examples/Makefile.am index 204e23df..c41ea05b 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -4,13 +4,7 @@ $(BOOST_CPPFLAGS) LDFLAGS = $(BOOST_LDFLAGS) -LDADD = \ -$(top_builddir)/libopmcore.la \ -$(BOOST_FILESYSTEM_LIB) \ -$(BOOST_SYSTEM_LIB) \ -$(BOOST_DATE_TIME_LIB) \ -$(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ -$(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +LDADD = $(top_builddir)/libopmcore.la noinst_PROGRAMS = \ scaneclipsedeck diff --git a/tests/Makefile.am b/tests/Makefile.am index d7e5f9ce..b8d95ec6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,13 +5,7 @@ $(BOOST_CPPFLAGS) LDFLAGS = $(BOOST_LDFLAGS) -LDADD = \ -$(top_builddir)/libopmcore.la \ -$(BOOST_FILESYSTEM_LIB) \ -$(BOOST_SYSTEM_LIB) \ -$(BOOST_DATE_TIME_LIB) \ -$(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ -$(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +LDADD = $(top_builddir)/libopmcore.la noinst_PROGRAMS = \ From f6146bd8bf826c62c46586b63a813dad6d2a7527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 23 Dec 2011 14:11:47 +0100 Subject: [PATCH 110/113] Added BOOST_LDFLAGS to LIBS to get it into libtool dependency. --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 0543f765..dd5f74ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,8 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = . tests examples CPPFLAGS += $(BOOST_CPPFLAGS) -LIBS += $(BOOST_FILESYSTEM_LIB) \ +LIBS += $(BOOST_LDFLAGS) \ + $(BOOST_FILESYSTEM_LIB) \ $(BOOST_SYSTEM_LIB) \ $(BOOST_DATE_TIME_LIB) \ $(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ From 79ba5608c5ae640b2a1b3c4a5bb656c5ddda49a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Tue, 3 Jan 2012 09:38:38 +0100 Subject: [PATCH 111/113] Implemented keyword TSTEP --- opm/core/eclipse/EclipseGridParser.cpp | 24 ++++++++++++------ opm/core/eclipse/EclipseGridParser.hpp | 1 + opm/core/eclipse/SpecialEclipseFields.hpp | 30 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index 12a36ff7..6466d2b7 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -95,7 +95,7 @@ namespace EclipseKeywords string("SGOF"), string("SWOF"), string("ROCK"), string("ROCKTAB"), string("WELSPECS"), string("COMPDAT"), string("WCONINJE"), string("WCONPROD"), string("WELTARG"), - string("EQUIL"), string("PVCDO"), + string("EQUIL"), string("PVCDO"), string("TSTEP"), // The following fields only have a dummy implementation // that allows us to ignore them. "SWFN", @@ -111,7 +111,7 @@ namespace EclipseKeywords string("NSTACK"), string("SATNUM"), string("RPTRST"), string("ROIP"), string("RWIP"), string("RWSAT"), string("RPR"), string("WBHP"), - string("WOIR"), string("TSTEP"), string("BOX"), + string("WOIR"), string("BOX"), string("COORDSYS"), string("PBVD") }; const int num_ignore_with_data = sizeof(ignore_with_data) / sizeof(ignore_with_data[0]); @@ -249,12 +249,20 @@ void EclipseGridParser::readImpl(istream& is) readVectorData(is, floatmap[keyword]); break; case SpecialField: { - std::tr1::shared_ptr sb_ptr = createSpecialField(is, keyword); - if (sb_ptr) { - specialmap[keyword] = sb_ptr; - } else { - THROW("Could not create field " << keyword); - } + map >::iterator pos = + specialmap.find(keyword); + if (pos == specialmap.end()) { + std::tr1::shared_ptr sb_ptr = + createSpecialField(is, keyword); + if (sb_ptr) { + specialmap[keyword] = sb_ptr; + } else { + THROW("Could not create field " << keyword); + } + } else { + std::tr1::shared_ptr sb_ptr = pos->second; + sb_ptr->read(is); + } break; } case IgnoreWithData: { diff --git a/opm/core/eclipse/EclipseGridParser.hpp b/opm/core/eclipse/EclipseGridParser.hpp index 59899633..c7ff48e4 100644 --- a/opm/core/eclipse/EclipseGridParser.hpp +++ b/opm/core/eclipse/EclipseGridParser.hpp @@ -142,6 +142,7 @@ public: SPECIAL_FIELD(WELTARG); SPECIAL_FIELD(EQUIL); SPECIAL_FIELD(PVCDO); + SPECIAL_FIELD(TSTEP); // The following fields only have a dummy implementation // that allows us to ignore them. diff --git a/opm/core/eclipse/SpecialEclipseFields.hpp b/opm/core/eclipse/SpecialEclipseFields.hpp index 6cc76fc4..387310ec 100644 --- a/opm/core/eclipse/SpecialEclipseFields.hpp +++ b/opm/core/eclipse/SpecialEclipseFields.hpp @@ -1408,6 +1408,36 @@ struct PVCDO : public SpecialBase } }; +struct TSTEP : public SpecialBase +{ + std::vector > tstep_; + + virtual std::string name() const {return std::string("TSTEP");} + + virtual void read(std::istream& is) + { + std::vector tstep; + readVectorData(is, tstep); + if (!tstep.empty()) { + tstep_.push_back(tstep); + } + } + + virtual void write(std::ostream& os) const + { + os << name() << '\n'; + for (int i=0; i<(int)tstep_.size(); ++i) { + copy(tstep_[i].begin(), tstep_[i].end(), + std::ostream_iterator(os, " ")); + os << '\n'; + } + } + + virtual void convertToSI(const EclipseUnits& units) + { + } +}; + struct MultRec : public SpecialBase { virtual void read(std::istream& is) From 9a12c4566c3af17e3f2f26bd3db616514d0113d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Tue, 3 Jan 2012 09:57:41 +0100 Subject: [PATCH 112/113] Use flat vector for TSTEP, implement convertToSI(). --- opm/core/eclipse/SpecialEclipseFields.hpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/opm/core/eclipse/SpecialEclipseFields.hpp b/opm/core/eclipse/SpecialEclipseFields.hpp index 387310ec..1990f824 100644 --- a/opm/core/eclipse/SpecialEclipseFields.hpp +++ b/opm/core/eclipse/SpecialEclipseFields.hpp @@ -1410,7 +1410,7 @@ struct PVCDO : public SpecialBase struct TSTEP : public SpecialBase { - std::vector > tstep_; + std::vector tstep_; virtual std::string name() const {return std::string("TSTEP");} @@ -1419,22 +1419,24 @@ struct TSTEP : public SpecialBase std::vector tstep; readVectorData(is, tstep); if (!tstep.empty()) { - tstep_.push_back(tstep); + tstep_.insert(tstep_.end(), tstep.begin(), tstep.end()); } } virtual void write(std::ostream& os) const { os << name() << '\n'; - for (int i=0; i<(int)tstep_.size(); ++i) { - copy(tstep_[i].begin(), tstep_[i].end(), - std::ostream_iterator(os, " ")); - os << '\n'; - } + copy(tstep_.begin(), tstep_.end(), + std::ostream_iterator(os, " ")); + os << '\n'; } virtual void convertToSI(const EclipseUnits& units) { + int num_steps = tstep_.size(); + for (int i = 0; i < num_steps; ++i) { + tstep_[i] *= units.time; + } } }; From 7e3d000ec865044eaafdfef4de011961c2068a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Tue, 3 Jan 2012 09:58:08 +0100 Subject: [PATCH 113/113] Minor reformatting. --- opm/core/eclipse/EclipseGridParser.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index 6466d2b7..a8e73845 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -252,17 +252,16 @@ void EclipseGridParser::readImpl(istream& is) map >::iterator pos = specialmap.find(keyword); if (pos == specialmap.end()) { - std::tr1::shared_ptr sb_ptr = - createSpecialField(is, keyword); - if (sb_ptr) { - specialmap[keyword] = sb_ptr; - } else { - THROW("Could not create field " << keyword); - } + std::tr1::shared_ptr sb_ptr = + createSpecialField(is, keyword); + if (sb_ptr) { + specialmap[keyword] = sb_ptr; } else { - std::tr1::shared_ptr sb_ptr = pos->second; - sb_ptr->read(is); + THROW("Could not create field " << keyword); } + } else { + pos->second->read(is); + } break; } case IgnoreWithData: {