mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-26 03:00:17 -06:00
Merge pull request #5589 from bska/sfunc-checkpoint-interface
Add Protocol for Populating Saturation Function End Points per Cell
This commit is contained in:
commit
c7b3e40bfa
@ -222,7 +222,9 @@ if (HAVE_ECL_INPUT)
|
||||
opm/simulators/utils/satfunc/OilPhaseConsistencyChecks.cpp
|
||||
opm/simulators/utils/satfunc/PhaseCheckBase.cpp
|
||||
opm/simulators/utils/satfunc/SatfuncConsistencyChecks.cpp
|
||||
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.cpp
|
||||
opm/simulators/utils/satfunc/ThreePointHorizontalConsistencyChecks.cpp
|
||||
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.cpp
|
||||
opm/simulators/utils/satfunc/WaterPhaseConsistencyChecks.cpp
|
||||
)
|
||||
endif()
|
||||
@ -409,6 +411,7 @@ if (HAVE_ECL_INPUT)
|
||||
tests/test_nonnc.cpp
|
||||
tests/test_GasSatfuncConsistencyChecks.cpp
|
||||
tests/test_OilSatfuncConsistencyChecks.cpp
|
||||
tests/test_SatfuncCheckPoint.cpp
|
||||
tests/test_SatfuncConsistencyChecks.cpp
|
||||
tests/test_SatfuncConsistencyChecks_parallel.cpp
|
||||
tests/test_ThreePointHorizontalSatfuncConsistencyChecks.cpp
|
||||
@ -1053,8 +1056,11 @@ if (HAVE_ECL_INPUT)
|
||||
opm/simulators/utils/satfunc/GasPhaseConsistencyChecks.hpp
|
||||
opm/simulators/utils/satfunc/OilPhaseConsistencyChecks.hpp
|
||||
opm/simulators/utils/satfunc/PhaseCheckBase.hpp
|
||||
opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp
|
||||
opm/simulators/utils/satfunc/SatfuncConsistencyChecks.hpp
|
||||
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.hpp
|
||||
opm/simulators/utils/satfunc/ThreePointHorizontalConsistencyChecks.hpp
|
||||
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp
|
||||
opm/simulators/utils/satfunc/WaterPhaseConsistencyChecks.hpp
|
||||
)
|
||||
endif()
|
||||
|
73
opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp
Normal file
73
opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SATFUNC_CHECKPOINT_INTERFACE_HPP_INCLUDED
|
||||
#define SATFUNC_CHECKPOINT_INTERFACE_HPP_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
namespace Opm {
|
||||
template <typename Scalar>
|
||||
struct EclEpsScalingPointsInfo;
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm::Satfunc::PhaseChecks {
|
||||
|
||||
/// Callback protocol for single saturation function consistency check point.
|
||||
///
|
||||
/// Intended to be used as a base class.
|
||||
///
|
||||
/// \tparam Scalar Element type. Typically \c float or \c double.
|
||||
template <typename Scalar>
|
||||
struct SatfuncCheckPointInterface
|
||||
{
|
||||
/// Virtual destructor for public inheritance
|
||||
virtual ~SatfuncCheckPointInterface() = default;
|
||||
|
||||
/// Compute locally unique, i.e., per MPI rank, ID of this check for
|
||||
/// a particular cell index.
|
||||
///
|
||||
/// Common examples include the drainage or imbibition region ID
|
||||
/// (i.e., SATNUM or IMBNUM) or the Cartesian block index of a cell.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \return Locally unique point ID for \p cellIdx. Nullopt if this
|
||||
/// check point does not apply to \p cellIdx. A common cause of the
|
||||
/// latter is running a region based check and the region already
|
||||
/// having been visited.
|
||||
virtual std::optional<std::size_t>
|
||||
pointID(const int cellIdx) const = 0;
|
||||
|
||||
/// Populate check point values for a particular cell.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \param[out] endPoints Set of saturation function end-points.
|
||||
/// Member function populateCheckPoint() assigns all data members
|
||||
/// and derived classes must abide by this requirement.
|
||||
virtual void
|
||||
populateCheckPoint(const int cellIdx,
|
||||
EclEpsScalingPointsInfo<Scalar>& endPoints) const = 0;
|
||||
};
|
||||
|
||||
} // namespace Opm::Satfunc::PhaseChecks
|
||||
|
||||
#endif // SATFUNC_CHECKPOINT_INTERFACE_HPP_INCLUDED
|
51
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.cpp
Normal file
51
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
#include <opm/material/fluidmatrixinteractions/EclEpsGridProperties.hpp>
|
||||
#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
|
||||
|
||||
#include <opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp>
|
||||
#include <opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp>
|
||||
|
||||
template <typename Scalar>
|
||||
void
|
||||
Opm::Satfunc::PhaseChecks::ScaledSatfuncCheckPoint<Scalar>::
|
||||
populateCheckPoint(const int cellIdx,
|
||||
EclEpsScalingPointsInfo<Scalar>& endPoints) const
|
||||
{
|
||||
this->unscaled_.populateCheckPoint(cellIdx, endPoints);
|
||||
|
||||
endPoints.extractScaled(*this->eclipseState_,
|
||||
*this->epsGridProps_, cellIdx);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Explicit Specialisations
|
||||
//
|
||||
// No other code below this separator
|
||||
// ===========================================================================
|
||||
|
||||
template class Opm::Satfunc::PhaseChecks::ScaledSatfuncCheckPoint<float>;
|
||||
template class Opm::Satfunc::PhaseChecks::ScaledSatfuncCheckPoint<double>;
|
113
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.hpp
Normal file
113
opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.hpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
||||
#define SCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
||||
|
||||
#include <opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp>
|
||||
#include <opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
namespace Opm {
|
||||
class EclipseState;
|
||||
class EclEpsGridProperties;
|
||||
|
||||
template <typename Scalar>
|
||||
struct EclEpsScalingPointsInfo;
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm::Satfunc::PhaseChecks {
|
||||
|
||||
/// Callbacks for defining the scaled saturation function consistency
|
||||
/// check point of a single active grid block.
|
||||
///
|
||||
/// \tparam Scalar Element type. Typically \c float or \c double.
|
||||
template <typename Scalar>
|
||||
class ScaledSatfuncCheckPoint : public SatfuncCheckPointInterface<Scalar>
|
||||
{
|
||||
public:
|
||||
/// Callback for translating active cell index to globally unique
|
||||
/// point ID.
|
||||
using LocalToGlobal = std::function<std::size_t(const int)>;
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// \param[in] unscaled Callbacks for inferring the end-points of
|
||||
/// the underlying saturation region.
|
||||
///
|
||||
/// \param[in] eclipseState Container of static properties such as
|
||||
/// the scaled saturation function end-points.
|
||||
///
|
||||
/// \param[in] epsGridProps Access interface for scaled saturation
|
||||
/// function end-points.
|
||||
///
|
||||
/// \param[in] localToGlobal Callback for translating active cell
|
||||
/// indices to globally unique point IDs.
|
||||
explicit ScaledSatfuncCheckPoint(const UnscaledSatfuncCheckPoint<Scalar>& unscaled,
|
||||
const EclipseState* eclipseState,
|
||||
const EclEpsGridProperties* epsGridProps,
|
||||
const LocalToGlobal& localToGlobal)
|
||||
: unscaled_ { unscaled }
|
||||
, eclipseState_ { eclipseState }
|
||||
, epsGridProps_ { epsGridProps }
|
||||
, localToGlobal_ { localToGlobal }
|
||||
{}
|
||||
|
||||
/// Compute global unique, i.e., across all MPI ranks, ID of this
|
||||
/// check for a particular cell index.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \return Globally unique point ID for \p cellIdx
|
||||
std::optional<std::size_t> pointID(const int cellIdx) const override
|
||||
{
|
||||
return { this->localToGlobal_(cellIdx) };
|
||||
}
|
||||
|
||||
/// Populate check point values for a particular cell.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \param[out] endPoints Set of saturation function end-points.
|
||||
void populateCheckPoint(const int cellIdx,
|
||||
EclEpsScalingPointsInfo<Scalar>& endPoints) const override;
|
||||
|
||||
private:
|
||||
/// Callbacks for inferring the end-points of the underlying
|
||||
/// saturation region.
|
||||
UnscaledSatfuncCheckPoint<Scalar> unscaled_;
|
||||
|
||||
/// Container of static properties such as the scaled saturation
|
||||
/// function end-points.
|
||||
const EclipseState* eclipseState_{nullptr};
|
||||
|
||||
/// Access interface for scaled saturation function end-points.
|
||||
const EclEpsGridProperties* epsGridProps_{nullptr};
|
||||
|
||||
/// Callback for translating active cell indices to globally unique
|
||||
/// point IDs.
|
||||
LocalToGlobal localToGlobal_{};
|
||||
};
|
||||
|
||||
} // namespace Opm::Satfunc::PhaseChecks
|
||||
|
||||
#endif // SCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
68
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.cpp
Normal file
68
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
|
||||
|
||||
#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
|
||||
|
||||
#include <opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
template <typename Scalar>
|
||||
std::optional<std::size_t>
|
||||
Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<Scalar>::
|
||||
pointID(const int cellIdx) const
|
||||
{
|
||||
const auto& [regPos, inserted] =
|
||||
this->seen_.insert((*this->region_)[cellIdx]);
|
||||
|
||||
// inserted == true => new/unseen region,
|
||||
// == false => previously seen region.
|
||||
return inserted
|
||||
? std::optional { static_cast<std::size_t>(*regPos) }
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
void
|
||||
Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<Scalar>::
|
||||
populateCheckPoint(const int cellIdx,
|
||||
EclEpsScalingPointsInfo<Scalar>& endPoints) const
|
||||
{
|
||||
endPoints.extractUnscaled(*this->unscaledEndPoints_.rtep,
|
||||
*this->unscaledEndPoints_.rfunc,
|
||||
(*this->region_)[cellIdx] - this->regIdxOffset_);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Explicit Specialisations
|
||||
//
|
||||
// No other code below this separator
|
||||
// ===========================================================================
|
||||
|
||||
template class Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<float>;
|
||||
template class Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<double>;
|
122
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp
Normal file
122
opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UNSCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
||||
#define UNSCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
||||
|
||||
#include <opm/simulators/utils/satfunc/SatfuncCheckPointInterface.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
template <typename Scalar>
|
||||
struct EclEpsScalingPointsInfo;
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm::satfunc {
|
||||
struct RawTableEndPoints;
|
||||
struct RawFunctionValues;
|
||||
} // namespace Opm::satfunc
|
||||
|
||||
namespace Opm::Satfunc::PhaseChecks {
|
||||
|
||||
/// Callbacks for defining the consistency check point of a single region.
|
||||
///
|
||||
/// \tparam Scalar Element type. Typically \c float or \c double.
|
||||
template <typename Scalar>
|
||||
class UnscaledSatfuncCheckPoint : public SatfuncCheckPointInterface<Scalar>
|
||||
{
|
||||
public:
|
||||
/// Collection of saturation function end-points and function values
|
||||
/// extracted from tabulated saturation functions.
|
||||
struct UnscaledEndPoints
|
||||
{
|
||||
/// Raw table end-points. Minimum, critical, and maximum
|
||||
/// saturation points for each phase for all tabulated
|
||||
/// saturation functions.
|
||||
const satfunc::RawTableEndPoints* rtep{nullptr};
|
||||
|
||||
/// Raw saturation function values. Maximum function values for
|
||||
/// all saturation functions in addition to relative
|
||||
/// permeability values at critical saturation points.
|
||||
const satfunc::RawFunctionValues* rfunc{nullptr};
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// \param[in] region Region index for each active cell on rank.
|
||||
///
|
||||
/// \param[in] regIdxOffset Region index offset. Pass one (1) if \p
|
||||
/// region contains one-based region indices.
|
||||
///
|
||||
/// \param[in] unscaledEndPoints Saturation function end-points for
|
||||
/// all tabulated saturation functions. Lifetime of members must
|
||||
/// exceed the \c UnscaledSatfuncCheckPoint object.
|
||||
explicit UnscaledSatfuncCheckPoint(const std::vector<int>* region,
|
||||
const int regIdxOffset,
|
||||
const UnscaledEndPoints& unscaledEndPoints)
|
||||
: unscaledEndPoints_ { unscaledEndPoints }
|
||||
, regIdxOffset_ { regIdxOffset }
|
||||
, region_ { region }
|
||||
{}
|
||||
|
||||
/// Compute locally unique, i.e., per MPI rank, ID of this check for
|
||||
/// a particular cell index.
|
||||
///
|
||||
/// Common examples include the drainage or imbibition region ID
|
||||
/// (i.e., SATNUM or IMBNUM) or the Cartesian block index of a cell.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \return Locally unique point ID for \p cellIdx. Nullopt if this
|
||||
/// check point does not apply to \p cellIdx. Typically because the
|
||||
/// underlying region of \p cellIdx has already been visited.
|
||||
std::optional<std::size_t> pointID(const int cellIdx) const override;
|
||||
|
||||
/// Populate check point values for a particular cell.
|
||||
///
|
||||
/// \param[in] cellIdx Active cell index on current rank.
|
||||
///
|
||||
/// \param[out] endPoints Set of saturation function end-points.
|
||||
void populateCheckPoint(const int cellIdx,
|
||||
EclEpsScalingPointsInfo<Scalar>& endPoints) const override;
|
||||
|
||||
private:
|
||||
/// Saturation function end-points for all tabulated saturation
|
||||
/// functions. Lifetime of members must exceed the \c
|
||||
/// UnscaledSatfuncCheckPoint object.
|
||||
UnscaledEndPoints unscaledEndPoints_;
|
||||
|
||||
/// Region index offset. Should be one (1) if region_ contains
|
||||
/// one-based region indices.
|
||||
int regIdxOffset_{};
|
||||
|
||||
/// Region index for each active cell on rank.
|
||||
const std::vector<int>* region_{nullptr};
|
||||
|
||||
/// Cache for visited ("seen") saturation regions.
|
||||
mutable std::unordered_set<int> seen_{};
|
||||
};
|
||||
|
||||
} // namespace Opm::Satfunc::PhaseChecks
|
||||
|
||||
#endif // UNSCALED_SATFUNC_CHECKPOINT_HPP_INCLUDED
|
768
tests/test_SatfuncCheckPoint.cpp
Normal file
768
tests/test_SatfuncCheckPoint.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define BOOST_TEST_MODULE TestSatfuncCheckPoint
|
||||
|
||||
#ifndef HAVE_MPI
|
||||
// Suppress GCC diagnostics of the form
|
||||
//
|
||||
// warning: "HAVE_MPI" is not defined, evaluates to 0
|
||||
//
|
||||
// when compiling with "-Wundef".
|
||||
#define HAVE_MPI 0
|
||||
#endif // HAVE_MPI
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/simulators/utils/satfunc/ScaledSatfuncCheckPoint.hpp>
|
||||
#include <opm/simulators/utils/satfunc/UnscaledSatfuncCheckPoint.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
#include <opm/material/fluidmatrixinteractions/EclEpsGridProperties.hpp>
|
||||
#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Parser/Parser.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
// ###########################################################################
|
||||
|
||||
namespace {
|
||||
Opm::satfunc::RawTableEndPoints exampleRTep()
|
||||
{
|
||||
auto rtep = Opm::satfunc::RawTableEndPoints{};
|
||||
|
||||
rtep.connate.gas .assign({ 0.0, 0.0, 0.0, 0.0 , });
|
||||
rtep.connate.water.assign({ 0.2, 0.1, 0.0, 0.25, });
|
||||
|
||||
rtep.critical.oil_in_gas .assign({ 0.1 , 0.125, 0.02, 0.35, });
|
||||
rtep.critical.oil_in_water.assign({ 0.2 , 0.225, 0.07, 0.5 , });
|
||||
rtep.critical.gas .assign({ 0.15, 0.257, 0.12, 0.04, });
|
||||
rtep.critical.water .assign({ 0.27, 0.325, 0.25, 0.42, });
|
||||
|
||||
rtep.maximum.gas .assign({ 0.8, 0.9, 1.0, 0.75, });
|
||||
rtep.maximum.water.assign({ 1.0, 1.0, 1.0, 0.8 , });
|
||||
|
||||
return rtep;
|
||||
}
|
||||
|
||||
Opm::satfunc::RawFunctionValues exampleRFunc()
|
||||
{
|
||||
auto rfunc = Opm::satfunc::RawFunctionValues{};
|
||||
|
||||
rfunc.kro.max.assign({ 0.75, 0.8, 0.85, 0.7, });
|
||||
rfunc.kro.rg .assign({ 0.62, 0.6, 0.78, 0.7, });
|
||||
rfunc.kro.rw .assign({ 0.53, 0.4, 0.82, 0.5, });
|
||||
|
||||
rfunc.krg.max.assign({ 1.0, 0.99, 0.98, 0.95, });
|
||||
rfunc.krg.r .assign({ 0.8, 0.79, 0.87, 0.75, });
|
||||
|
||||
rfunc.krw.max.assign({ 0.7, 0.69, 0.68, 0.65, });
|
||||
rfunc.krw.r .assign({ 0.5, 0.49, 0.48, 0.45, });
|
||||
|
||||
rfunc.pc.g.assign({ 0.0, 1.0, 2.0, 3.0, });
|
||||
rfunc.pc.w.assign({ 10.0, 8.5, 7.0, 5.5, });
|
||||
|
||||
return rfunc;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Unscaled_Curve)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(All_Regions)
|
||||
{
|
||||
using CurvePt = Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<double>;
|
||||
|
||||
const auto satnum = std::vector { 1, 2, 3, 4, };
|
||||
const auto rtep = exampleRTep();
|
||||
const auto rfunc = exampleRFunc();
|
||||
|
||||
const auto curvePt = CurvePt {
|
||||
&satnum, 1, CurvePt::UnscaledEndPoints { &rtep, &rfunc }
|
||||
};
|
||||
|
||||
{
|
||||
const auto id = curvePt.pointID(0);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(0) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{1});
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(0).has_value(),
|
||||
"pointID(0) must NOT return a value on second call");
|
||||
}
|
||||
|
||||
{
|
||||
const auto id = curvePt.pointID(1);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(1) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{2});
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(1).has_value(),
|
||||
"pointID(1) must NOT return a value on second call");
|
||||
}
|
||||
|
||||
{
|
||||
const auto id = curvePt.pointID(2);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(2) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{3});
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(0).has_value(),
|
||||
"pointID(2) must NOT return a value on second call");
|
||||
}
|
||||
|
||||
{
|
||||
const auto id = curvePt.pointID(3);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(3) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{4});
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(0).has_value(),
|
||||
"pointID(3) must NOT return a value on second call");
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 0 (SATNUM = 1).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(0, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.2, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.27, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.15, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.2 , 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.1 , 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.8, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 10.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.53, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.62, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.7, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.75, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.75, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 1.0, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 0. Intentionally
|
||||
// same as previous. Member function populateCheckPoint() should not
|
||||
// care that we've called the function with the same arguments before.
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(0, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.2, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.27, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.15, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.2 , 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.1 , 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.8, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 10.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.53, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.62, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.7, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.75, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.75, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 1.0, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 1 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(1, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.325, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.257, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.225, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.125, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.49, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.79, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.4, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.69, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.99, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 2 (SATNUM = 3).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(2, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.25, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.12, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.07, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.02, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 7.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 2.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.48, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.87, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.82, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.78, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.68, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.85, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.85, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.98, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 3 (SATNUM = 4).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(3, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.25, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.42, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.04, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.35, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.75, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 5.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 3.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.45, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.75, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.7, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.65, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.7, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.7, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.95, 1.0e-8);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Same_Region)
|
||||
{
|
||||
using CurvePt = Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<double>;
|
||||
|
||||
const auto satnum = std::vector { 2, 2, 2, 2, };
|
||||
const auto rtep = exampleRTep();
|
||||
const auto rfunc = exampleRFunc();
|
||||
|
||||
const auto curvePt = CurvePt {
|
||||
&satnum, 1, CurvePt::UnscaledEndPoints { &rtep, &rfunc }
|
||||
};
|
||||
|
||||
{
|
||||
const auto id = curvePt.pointID(0);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(0) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{2});
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(0).has_value(),
|
||||
"pointID(0) must NOT return a value on second call");
|
||||
}
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(1).has_value(),
|
||||
"pointID(1) must NOT return a value on first call");
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(2).has_value(),
|
||||
"pointID(2) must NOT return a value on first call");
|
||||
|
||||
BOOST_CHECK_MESSAGE(! curvePt.pointID(3).has_value(),
|
||||
"pointID(3) must NOT return a value on first call");
|
||||
|
||||
// Unscaled saturation function end-points in cell 0 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(0, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.325, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.257, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.225, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.125, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.49, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.79, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.4, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.69, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.99, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 1 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(1, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.325, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.257, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.225, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.125, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.49, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.79, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.4, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.69, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.99, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 2 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(2, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.325, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.257, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.225, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.125, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.49, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.79, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.4, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.69, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.99, 1.0e-8);
|
||||
}
|
||||
|
||||
// Unscaled saturation function end-points in cell 3 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<double>{};
|
||||
curvePt.populateCheckPoint(3, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.325, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.257, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.225, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.125, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.49, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.79, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.4, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6, 1.0e-8);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.69, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8, 1.0e-8);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.99, 1.0e-8);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // Unscaled_Curve
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Scaled_Curve)
|
||||
|
||||
namespace {
|
||||
Opm::EclipseState scaledEndpointProps()
|
||||
{
|
||||
return Opm::EclipseState {
|
||||
Opm::Parser{}.parseString(R"(RUNSPEC
|
||||
DIMENS
|
||||
1 5 1 /
|
||||
ENDSCALE
|
||||
/
|
||||
TABDIMS
|
||||
3 /
|
||||
OIL
|
||||
GAS
|
||||
WATER
|
||||
GRID
|
||||
DXV
|
||||
100.0 /
|
||||
DYV
|
||||
5*20.0 /
|
||||
DZV
|
||||
5.0 /
|
||||
DEPTHZ
|
||||
12*2000.0 /
|
||||
PORO
|
||||
5*0.3 /
|
||||
PROPS
|
||||
SCALECRS
|
||||
'YES' /
|
||||
SWOF
|
||||
0.0 0.0 1.0 0.0
|
||||
1.0 1.0 0.0 0.0
|
||||
/
|
||||
/
|
||||
/
|
||||
SGOF
|
||||
0.0 0.0 1.0 0.0
|
||||
1.0 1.0 0.0 0.0
|
||||
/
|
||||
/
|
||||
/
|
||||
SWL
|
||||
0.05 0.1 0.15 0.2 0.27 /
|
||||
SWCR
|
||||
0.06 0.11 0.16 0.21 0.3 /
|
||||
SWU
|
||||
0.98 0.97 0.96 0.95 0.94 /
|
||||
SGL
|
||||
0.01 0.02 0.03 0.04 0.05 /
|
||||
SGCR
|
||||
0.1 0.11 0.12 0.13 0.14 /
|
||||
SGU
|
||||
0.89 0.9 0.91 0.92 0.93 /
|
||||
SOWCR
|
||||
0.21 0.23 0.25 0.27 0.29 /
|
||||
SOGCR
|
||||
0.15 0.16 0.17 0.18 0.19 /
|
||||
KRW
|
||||
0.72 0.77 0.82 0.87 0.92 /
|
||||
KRWR
|
||||
0.6 0.63 0.66 0.71 0.65 /
|
||||
KRG
|
||||
0.85 0.84 0.86 0.83 0.87 /
|
||||
KRGR
|
||||
5*0.775 /
|
||||
KRORW
|
||||
0.55 0.65 0.65 0.7 0.6 /
|
||||
-- No KRORG => use unscaled function values
|
||||
REGIONS
|
||||
SATNUM
|
||||
1 3 2 2 1 /
|
||||
END
|
||||
)")
|
||||
};
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
BOOST_AUTO_TEST_CASE(All_Cells)
|
||||
{
|
||||
using UnscaledCurvePt = Opm::Satfunc::PhaseChecks::UnscaledSatfuncCheckPoint<float>;
|
||||
using ScaledCurvePt = Opm::Satfunc::PhaseChecks::ScaledSatfuncCheckPoint<float>;
|
||||
|
||||
const auto es = scaledEndpointProps();
|
||||
|
||||
const auto* satnum = &es.fieldProps().get_int("SATNUM"); // {1, 3, 2, 2, 1}
|
||||
const auto rtep = exampleRTep();
|
||||
const auto rfunc = exampleRFunc();
|
||||
|
||||
const auto unscaledCurvePt = UnscaledCurvePt {
|
||||
satnum, 1, UnscaledCurvePt::UnscaledEndPoints { &rtep, &rfunc }
|
||||
};
|
||||
|
||||
const auto epsGridProps = Opm::EclEpsGridProperties { es, /* useImbibition = */ false };
|
||||
|
||||
const auto scaledCurvePt = ScaledCurvePt {
|
||||
unscaledCurvePt, &es, &epsGridProps,
|
||||
[](const auto& i) { return static_cast<std::size_t>(i); }
|
||||
};
|
||||
|
||||
{
|
||||
const auto id = scaledCurvePt.pointID(0);
|
||||
BOOST_REQUIRE_MESSAGE(id.has_value(),
|
||||
"pointID(0) must return a value on first call");
|
||||
|
||||
BOOST_CHECK_EQUAL(*id, std::size_t{0});
|
||||
|
||||
BOOST_CHECK_MESSAGE(scaledCurvePt.pointID(0).has_value(),
|
||||
"pointID(0) must return a value on second call");
|
||||
}
|
||||
|
||||
// Scaled saturation function end-points in cell 0 (SATNUM = 1).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<float>{};
|
||||
scaledCurvePt.populateCheckPoint(0, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.05f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.01f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.06f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.1f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.21f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.15f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.98f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.89f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 10.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 0.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.6f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.775f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.55f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.62f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.72f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.75f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.75f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.85f, 1.0e-6f);
|
||||
}
|
||||
|
||||
// Scaled saturation function end-points in cell 1 (SATNUM = 3).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<float>{};
|
||||
scaledCurvePt.populateCheckPoint(1, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.1f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.02f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.11f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.11f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.23f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.16f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.97f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.9f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 7.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 2.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.63f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.775f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.65f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.78f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.77f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.85f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.85f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.84f, 1.0e-6f);
|
||||
}
|
||||
|
||||
// Scaled saturation function end-points in cell 2 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<float>{};
|
||||
scaledCurvePt.populateCheckPoint(2, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.15f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.03f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.16f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.12f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.25f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.17f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.96f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.91f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.66f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.775f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.65f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.82f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.86f, 1.0e-6f);
|
||||
}
|
||||
|
||||
// Scaled saturation function end-points in cell 3 (SATNUM = 2).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<float>{};
|
||||
scaledCurvePt.populateCheckPoint(3, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.2f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.04f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.21f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.13f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.27f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.18f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.95f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.92f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 8.5f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.71f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.775f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.7f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.6f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.87f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.8f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.8f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.83f, 1.0e-6f);
|
||||
}
|
||||
|
||||
// Scaled saturation function end-points in cell 4 (SATNUM = 1).
|
||||
{
|
||||
auto endPoints = Opm::EclEpsScalingPointsInfo<float>{};
|
||||
scaledCurvePt.populateCheckPoint(4, endPoints);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swl, 0.27f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgl, 0.05f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swcr, 0.3f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgcr, 0.14f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sowcr, 0.29f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sogcr, 0.19f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Swu, 0.94f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Sgu, 0.93f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcow, 10.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxPcgo, 0.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.pcowLeverettFactor, 1.0f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.pcgoLeverettFactor, 1.0f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.Krwr, 0.65f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krgr, 0.775f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorw, 0.6f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.Krorg, 0.62f, 1.0e-6f);
|
||||
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrw, 0.92f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrow, 0.75f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrog, 0.75f, 1.0e-6f);
|
||||
BOOST_CHECK_CLOSE(endPoints.maxKrg, 0.87f, 1.0e-6f);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // Scaled_Curve
|
Loading…
Reference in New Issue
Block a user